=== modified file 'modules/simpletest/drupal_web_test_case.php' --- modules/simpletest/drupal_web_test_case.php 2008-08-23 07:42:54 +0000 +++ modules/simpletest/drupal_web_test_case.php 2008-08-28 05:14:32 +0000 @@ -20,9 +20,12 @@ class DrupalWebTestCase { protected $db_prefix_original; protected $original_file_directory; - var $_results = array('#pass' => 0, '#fail' => 0, '#exception' => 0); + var $_results = array('#pass' => 0, '#fail' => 0, '#exception' => 0, '#unexpected pass' => 0, '#expected fail' => 0); + var $_assertions = array(); + var $expectedFail = FALSE; + /** * Constructor for DrupalWebTestCase. * @@ -34,6 +37,18 @@ class DrupalWebTestCase { } /** + * The next assert is expected to fail. + * + * Use $this->expectedFail->assert... to mark the assert as an expected fail. + * If your test reveals a bug then use this function. + */ + protected function expectedFail() { + $this->expectedFail = TRUE; + return $this; + } + + + /** * This function stores the assert. Do not call directly. * * @param $status @@ -52,6 +67,13 @@ class DrupalWebTestCase { */ protected function _assert($status, $message = '', $group = 'Other', $custom_caller = NULL) { global $db_prefix; + if ($this->expectedFail) { + $this->expectedFail = FALSE; + $message .= t('This is expected to fail due to a known bug.'); + if (is_bool($status)) { + $status = $status ? 'unexpected pass' : 'expected fail'; + } + } if (is_bool($status)) { $status = $status ? 'pass' : 'fail'; } @@ -72,13 +94,13 @@ class DrupalWebTestCase { $db_prefix = $this->db_prefix_original; db_insert('simpletest')->fields(array( 'test_id' => $this->test_id, - 'test_class' => get_class($this), - 'status' => $status, - 'message' => substr($message, 0, 255), // Some messages are too long for the database. - 'message_group' => $group, - 'caller' => $function['function'], - 'line' => $function['line'], - 'file' => $function['file'], + 'test_class' => get_class($this), + 'status' => $status, + 'message' => substr($message, 0, 255), // Some messages are too long for the database. + 'message_group' => $group, + 'caller' => $function['function'], + 'line' => $function['line'], + 'file' => $function['file'], ))->execute(); $this->_assertions[] = array( 'status' => $status, @@ -405,7 +427,7 @@ class DrupalWebTestCase { node_types_rebuild(); $this->assertEqual($saved_type, SAVED_NEW, t('Created content type %type.', array('%type' => $type->type))); - + // Reset permissions so that permissions for this content type are available. $this->checkPermissions(array(), TRUE); @@ -645,7 +667,7 @@ class DrupalWebTestCase { // Generate temporary prefixed database to ensure that tests have a clean starting point. $db_prefix = 'simpletest' . mt_rand(1000, 1000000); - + include_once './includes/install.inc'; drupal_install_system(); @@ -659,7 +681,7 @@ class DrupalWebTestCase { // stale data for the previous run's database prefix and all // calls to it will fail. drupal_get_schema(NULL, TRUE); - + // Run default profile tasks. $task = 'profile'; default_profile_tasks($task, ''); === modified file 'modules/simpletest/simpletest.css' --- modules/simpletest/simpletest.css 2008-06-24 21:51:02 +0000 +++ modules/simpletest/simpletest.css 2008-08-27 20:23:51 +0000 @@ -24,11 +24,13 @@ table#simpletest-form-table tr.simpletes background-color: #EDF5FA !important; } -div.simpletest-pass { +div.simpletest-pass, +div.simpletest-expected-fail { color: #33a333; } -div.simpletest-fail { +div.simpletest-fail, +div.simpletest-unexpected-pass { color: #a30000; } === modified file 'modules/simpletest/simpletest.install' --- modules/simpletest/simpletest.install 2008-08-16 20:57:14 +0000 +++ modules/simpletest/simpletest.install 2008-08-27 20:10:03 +0000 @@ -160,7 +160,7 @@ function simpletest_schema() { ), 'status' => array( 'type' => 'varchar', - 'length' => 9, + 'length' => 17 'not null' => TRUE, 'default' => '', 'description' => t('Message status. Core understands pass, fail, exception.'), === modified file 'modules/simpletest/simpletest.module' --- modules/simpletest/simpletest.module 2008-08-21 19:36:35 +0000 +++ modules/simpletest/simpletest.module 2008-08-28 05:13:09 +0000 @@ -70,6 +70,8 @@ function simpletest_test_form() { '#pass' => 0, '#fail' => 0, '#exception' => 0, + '#unexpected pass' => 0, + '#expected fail' => 0, '#weight' => -10, ); $form['summary'] = $summary; @@ -79,6 +81,8 @@ function simpletest_test_form() { 'pass' => theme('image', 'misc/watchdog-ok.png'), 'fail' => theme('image', 'misc/watchdog-error.png'), 'exception' => theme('image', 'misc/watchdog-warning.png'), + 'unexpected pass' => theme('image', 'misc/watchdog-error.png'), + 'expected fail' => theme('image', 'misc/watchdog-warning.png'), ); $header = array(t('Message'), t('Group'), t('Filename'), t('Line'), t('Function'), array('colspan' => 2, 'data' => t('Status'))); while ($result = db_fetch_object($results)) { @@ -93,7 +97,8 @@ function simpletest_test_form() { $element['summary'] = $summary; } $status = $result->status; - // This reporter can only handle pass, fail and exception. + // This reporter can only handle pass, fail, exception, unexpected pass + // and expected fail. if (isset($map[$status])) { $element['#title'] = $info['name']; $status_index = '#'. $status; @@ -109,7 +114,7 @@ function simpletest_test_form() { $result->caller, $map[$status], ), - 'class' => "simpletest-$status", + 'class' => str_replace(' ', '-', "simpletest-$status"), ); } unset($element); @@ -127,7 +132,7 @@ function simpletest_test_form() { $group_ok = TRUE; foreach ($elements as $class => &$element) { $info = $uncategorized_tests[$class]->getInfo(); - $ok = $element['summary']['#fail'] + $element['summary']['#exception'] == 0; + $ok = $element['summary']['#fail'] + $element['summary']['#exception'] + $element['summary']['#unexpected pass'] == 0; $element += array( '#type' => 'fieldset', '#collapsible' => TRUE, @@ -270,10 +275,12 @@ function theme_simpletest_result_summary } function _simpletest_format_summary_line($summary) { - return t('@pass, @fail, @exception', array( + return t('@pass, @fail, @exception, @unexpected_pass, @expected_fail', 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'), + '@unexpected_pass' => format_plural(isset($summary['#unexpected pass']) ? $summary['#unexpected pass'] : 0, '1 unexpected pass', '@count unexpected passes'), + '@expected_fail' => format_plural(isset($summary['#expected fail']) ? $summary['#expected fail'] : 0, '1 expected fail', '@count unexpected fails'), )); } @@ -350,7 +357,7 @@ function _simpletest_batch_operation($te // 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, '#unexpected pass', '#expected fail'); } else { // Nth iteration: get the current values where we last stored them. @@ -374,7 +381,8 @@ function _simpletest_batch_operation($te $test_results[$test_class]['#name'] = $info['name']; $items = array(); foreach (element_children($test_results) as $class) { - $items[] = '