diff --git a/core/modules/simpletest/css/simpletest.module.css b/core/modules/simpletest/css/simpletest.module.css
index 86bd04b..0337e62 100644
--- a/core/modules/simpletest/css/simpletest.module.css
+++ b/core/modules/simpletest/css/simpletest.module.css
@@ -30,8 +30,12 @@ th.simpletest_test {
background-color: #edf5fa;
color: #494949;
}
+.simpletest-test-select .form-item {
+ margin-bottom: 0;
+ margin-top: 0;
+}
-table#simpletest-form-table tr.simpletest-group label {
+#simpletest-form-table tr.simpletest-group label {
display: inline;
}
diff --git a/core/modules/simpletest/lib/Drupal/simpletest/Form/SimpletestResultsForm.php.orig b/core/modules/simpletest/lib/Drupal/simpletest/Form/SimpletestResultsForm.php.orig
new file mode 100644
index 0000000..61c6c61
--- /dev/null
+++ b/core/modules/simpletest/lib/Drupal/simpletest/Form/SimpletestResultsForm.php.orig
@@ -0,0 +1,318 @@
+get('database'));
+ }
+
+ /**
+ * Constructs a \Drupal\simpletest\Form\SimpletestResultsForm object.
+ *
+ * @param \Drupal\Core\Database\Connection $database
+ * The database connection service.
+ */
+ public function __construct(Connection $database) {
+ $this->database = $database;
+ // Initialize image mapping property.
+ $image_pass = array(
+ '#theme' => 'image',
+ '#uri' => 'core/misc/watchdog-ok.png',
+ '#width' => 18,
+ '#height' => 18,
+ '#alt' => t('Pass'),
+ );
+ $image_fail = array(
+ '#theme' => 'image',
+ '#uri' => 'core/misc/watchdog-error.png',
+ '#width' => 18,
+ '#height' => 18,
+ '#alt' => t('Fail'),
+ );
+ $image_exception = array(
+ '#theme' => 'image',
+ '#uri' => 'core/misc/watchdog-warning.png',
+ '#width' => 18,
+ '#height' => 18,
+ '#alt' => t('Exception'),
+ );
+ $image_debug = array(
+ '#theme' => 'image',
+ '#uri' => 'core/misc/watchdog-warning.png',
+ '#width' => 18,
+ '#height' => 18,
+ '#alt' => t('Debug'),
+ );
+ $this->statusImageMap = array(
+ 'pass' => drupal_render($image_pass),
+ 'fail' => drupal_render($image_fail),
+ 'exception' => drupal_render($image_exception),
+ 'debug' => drupal_render($image_debug),
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getFormID() {
+ return 'simpletest_results_form';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildForm(array $form, array &$form_state, $test_id = NULL) {
+ // Make sure there are test results to display and a re-run is not being
+ // performed.
+ $results = array();
+
+ if (is_numeric($test_id) && !$results = $this->getResults($test_id)) {
+ drupal_set_message(t('No test results to display.'), 'error');
+ return new RedirectResponse(url('admin/config/development/testing', array('absolute' => TRUE)));
+ }
+
+ // Load all classes and include CSS.
+ $form['#attached']['css'][] = drupal_get_path('module', 'simpletest') . '/css/simpletest.module.css';
+
+ // Keep track of which test cases passed or failed.
+ $filter = array(
+ 'pass' => array(),
+ 'fail' => array(),
+ );
+
+ // Summary result widget.
+ $form['result'] = array(
+ '#type' => 'fieldset',
+ '#title' => t('Results'),
+ );
+ $form['result']['summary'] = $summary = array(
+ '#pass' => 0,
+ '#fail' => 0,
+ '#exception' => 0,
+ '#debug' => 0,
+ );
+
+ simpletest_classloader_register();
+
+ // Cycle through each test group.
+ $header = array(
+ t('Message'),
+ t('Group'),
+ t('Filename'),
+ t('Line'),
+ t('Function'),
+ array('colspan' => 2, 'data' => t('Status'))
+ );
+ $form['result']['results'] = array();
+ foreach ($results as $group => $assertions) {
+ // Create group details with summary information.
+ $info = call_user_func(array($group, 'getInfo'));
+ $form['result']['results'][$group] = array(
+ '#type' => 'details',
+ '#title' => $info['name'],
+ '#description' => $info['description'],
+ );
+ $form['result']['results'][$group]['summary'] = $summary;
+ $group_summary =& $form['result']['results'][$group]['summary'];
+
+ // Create table of assertions for the group.
+ $rows = array();
+ foreach ($assertions as $assertion) {
+ $row = array();
+ $row[] = $assertion->message;
+ $row[] = $assertion->message_group;
+ $row[] = drupal_basename($assertion->file);
+ $row[] = $assertion->line;
+ $row[] = $assertion->function;
+ $row[] = $this->statusImageMap[$assertion->status];
+
+ $class = 'simpletest-' . $assertion->status;
+ if ($assertion->message_group == 'Debug') {
+ $class = 'simpletest-debug';
+ }
+ $rows[] = array('data' => $row, 'class' => array($class));
+
+ $group_summary['#' . $assertion->status]++;
+ $form['result']['summary']['#' . $assertion->status]++;
+ }
+ $form['result']['results'][$group]['table'] = array(
+ '#type' => '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'];
+
+ // Store test group (class) as for use in filter.
+ $filter[$group_summary['#ok'] ? 'pass' : 'fail'][] = $group;
+
+ // Render summary information.
+ $group_summary += array(
+ '#prefix' => '
',
+ '#markup' => _simpletest_format_summary_line($group_summary),
+ '#suffix' => '
',
+ );
+ }
+
+ // Overal summary status.
+ $form['result']['summary']['#ok'] = $form['result']['summary']['#fail'] + $form['result']['summary']['#exception'] == 0;
+
+ // Render overall summary.
+ $form['result']['summary'] += array(
+ '#prefix' => '',
+ '#markup' => _simpletest_format_summary_line($form['result']['summary']),
+ '#suffix' => '
',
+ );
+
+ // Actions.
+ $form['#action'] = url('admin/config/development/testing/results/re-run');
+ $form['action'] = array(
+ '#type' => 'fieldset',
+ '#title' => t('Actions'),
+ '#attributes' => array('class' => array('container-inline')),
+ '#weight' => -11,
+ );
+
+ $form['action']['filter'] = array(
+ '#type' => 'select',
+ '#title' => 'Filter',
+ '#options' => array(
+ 'all' => t('All (@count)', array('@count' => count($filter['pass']) + count($filter['fail']))),
+ 'pass' => t('Pass (@count)', array('@count' => count($filter['pass']))),
+ 'fail' => t('Fail (@count)', array('@count' => count($filter['fail']))),
+ ),
+ );
+ $form['action']['filter']['#default_value'] = ($filter['fail'] ? 'fail' : 'all');
+
+ // Categorized test classes for to be used with selected filter value.
+ $form['action']['filter_pass'] = array(
+ '#type' => 'hidden',
+ '#default_value' => implode(',', $filter['pass']),
+ );
+ $form['action']['filter_fail'] = array(
+ '#type' => 'hidden',
+ '#default_value' => implode(',', $filter['fail']),
+ );
+
+ $form['action']['op'] = array(
+ '#type' => 'submit',
+ '#value' => t('Run tests'),
+ );
+
+ $form['action']['return'] = array(
+ '#type' => 'link',
+ '#title' => t('Return to list'),
+ '#href' => 'admin/config/development/testing',
+ );
+
+ if (is_numeric($test_id)) {
+ simpletest_clean_results_table($test_id);
+ }
+
+ return $form;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validateForm(array &$form, array &$form_state) {
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function submitForm(array &$form, array &$form_state) {
+ $pass = $form_state['values']['filter_pass'] ? explode(',', $form_state['values']['filter_pass']) : array();
+ $fail = $form_state['values']['filter_fail'] ? explode(',', $form_state['values']['filter_fail']) : array();
+
+ if ($form_state['values']['filter'] == 'all') {
+ $classes = array_merge($pass, $fail);
+ }
+ elseif ($form_state['values']['filter'] == 'pass') {
+ $classes = $pass;
+ }
+ else {
+ $classes = $fail;
+ }
+
+ if (!$classes) {
+ $form_state['redirect'] = 'admin/config/development/testing';
+ return;
+ }
+
+ $form_execute = array();
+ $form_state_execute = array('values' => array());
+ foreach ($classes as $class) {
+ $form_state_execute['values'][$class] = 1;
+ }
+
+ // Submit the simpletest test form to rerun the tests.
+ $simpletest_test_form = new SimpletestTestForm();
+ $simpletest_test_form->submitForm($form_execute, $form_state_execute);
+ $form_state['redirect'] = $form_state_execute['redirect'];
+ }
+
+ /**
+ * Get test results for $test_id.
+ *
+ * @param int $test_id
+ * The test_id to retrieve results of.
+ *
+ * @return array
+ * Array of results grouped by test_class.
+ */
+ protected function getResults($test_id) {
+ $results = $this->database->select('simpletest')
+ ->fields('simpletest')
+ ->condition('test_id', $test_id)
+ ->orderBy('test_class')
+ ->orderBy('message_id')
+ ->execute();
+
+ $test_results = array();
+ foreach ($results as $result) {
+ if (!isset($test_results[$result->test_class])) {
+ $test_results[$result->test_class] = array();
+ }
+ $test_results[$result->test_class][] = $result;
+ }
+
+ return $test_results;
+ }
+
+}
diff --git a/core/modules/simpletest/simpletest.module b/core/modules/simpletest/simpletest.module
index 587b6c0..68a7e06 100644
--- a/core/modules/simpletest/simpletest.module
+++ b/core/modules/simpletest/simpletest.module
@@ -77,10 +77,7 @@ function simpletest_theme() {
'simpletest_test_table' => array(
'render element' => 'table',
'file' => 'simpletest.theme.inc',
- ),
- 'simpletest_result_summary' => array(
- 'render element' => 'form',
- 'file' => 'simpletest.theme.inc',
+ 'template' => 'simpletest-test-table',
),
);
}
diff --git a/core/modules/simpletest/simpletest.theme.inc b/core/modules/simpletest/simpletest.theme.inc
index 31cbb02..48e2eeb 100644
--- a/core/modules/simpletest/simpletest.theme.inc
+++ b/core/modules/simpletest/simpletest.theme.inc
@@ -6,26 +6,20 @@
*/
/**
- * Returns an HTML table for a test list generated by simpletest_test_form().
+ * use Drupal\Core\Template\Attribute;
*
- * @param $variables
+ **
+ * Prepares variables for test list table templates.
+ *
+ * Default template: simpletest-test-table.html.twig.
+ *
+ * @param array $variables
* An associative array containing:
* - table: A render element representing the table.
- *
- * @ingroup themeable
- */
-function theme_simpletest_test_table($variables) {
+ */ function template_preprocess_simpletest_test_table(&$variables) {
$table = $variables['table'];
drupal_add_library('simpletest', 'drupal.simpletest');
-
- // Create header for test selection table.
- $header = array(
- array('class' => array('select-all')),
- array('data' => t('Test'), 'class' => array('simpletest_test')),
- array('data' => t('Description'), 'class' => array('simpletest_description')),
- );
-
// Define the images used to expand/collapse the test groups.
$image_collapsed = array(
'#theme' => 'image',
@@ -95,69 +89,42 @@ function theme_simpletest_test_table($variables) {
// Sorting $element by children's #title attribute instead of by class name.
uasort($element, 'element_sort_by_title');
+ $variables['test_groups'][$key]->tests = array();
+
// Cycle through each test within the current group.
foreach (element_children($element) as $test_name) {
$test = $element[$test_name];
- $row = array();
+ $test_data = new stdClass();
+ $test_data->attributes = new Attribute(array('class' => array()));
+ $test_data->id = $test['#id'];
$current_js['testNames'][] = $test['#id'];
// Store test title and description so that checkbox won't render them.
- $title = $test['#title'];
- $description = $test['#description'];
-
+ $test_data = new stdClass();
+ $test_data->attributes = new Attribute(array('class' => array()));
+ $test_data->id = $test['#id'];
$test['#title_display'] = 'invisible';
- unset($test['#description']);
-
+
// Test name is used to determine what tests to run.
$test['#name'] = $test_name;
- $row[] = array(
- 'data' => drupal_render($test),
- 'class' => array('simpletest-test-select'),
- );
- $row[] = array(
- 'data' => '',
- 'class' => array('simpletest-test-label', 'table-filter-text-source'),
- );
- $row[] = array(
- 'data' => '' . format_string('@description (@class)', array('@description' => $description, '@class' => $test_name)) . '
',
- 'class' => array('simpletest-test-description', 'table-filter-text-source'),
- );
-
- $rows[] = array('data' => $row, 'class' => array($test_class . '-test', ($collapsed ? 'js-hide' : '')));
+ // Add the checkbox field.
+ $test_data->field = $test;
+
+ $test_data->attributes['class'][] = $test_class . '-test';
+ $test_data->attributes['class'][] = ($collapsed ? 'js-hide' : '');
+
+ $variables['test_groups'][$key]->tests[$test_name] = $test_data;
}
$js['simpletest-test-group-' . $test_class] = $current_js;
- unset($table[$key]);
- }
+
+ }
// Add js array of settings.
drupal_add_js(array('simpleTest' => $js), 'setting');
- if (empty($rows)) {
- return '' . t('No tests to display.') . '';
- }
- else {
- $simpletest_form_table = array(
- '#theme' => 'table',
- '#header' => $header,
- '#rows' => $rows,
- '#attributes' => array('id' => 'simpletest-form-table'),
- );
+
return drupal_render($simpletest_form_table);
}
}
-
-/**
- * Returns HTML for the summary status of a simpletest result.
- *
- * @param $variables
- * An associative array containing:
- * - form: A render element representing the form.
- *
- * @ingroup themeable
- */
-function theme_simpletest_result_summary($variables) {
- $form = $variables['form'];
- return '' . _simpletest_format_summary_line($form) . '
';
-}
diff --git a/core/modules/simpletest/templates/simpletest-test-table.html.twig b/core/modules/simpletest/templates/simpletest-test-table.html.twig
new file mode 100644
index 0000000..f6a94be
--- /dev/null
+++ b/core/modules/simpletest/templates/simpletest-test-table.html.twig
@@ -0,0 +1,46 @@
+{#
+/**
+ * @file
+ * Default theme implementation for the content of simpletest test table.
+ *
+ * Available variables:
+ * - table: A simpletest table.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_simpletest_test_table()
+ *
+ * @ingroup themeable
+ */
+#}
+