View source  
  <?php
namespace Drupal\simpletest\Form;
use Drupal\Core\Database\Connection;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormState;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Test\EnvironmentCleanerInterface;
use Drupal\Core\Url;
use Drupal\simpletest\TestDiscovery;
use Symfony\Component\DependencyInjection\ContainerInterface;
class SimpletestResultsForm extends FormBase {
  
  protected $statusImageMap;
  
  protected $database;
  
  protected $cleaner;
  
  public static function create(ContainerInterface $container) {
    return new static($container
      ->get('database'), $container
      ->get('environment_cleaner'));
  }
  
  public function __construct(Connection $database, EnvironmentCleanerInterface $cleaner) {
    $this->database = $database;
    $this->cleaner = $cleaner;
  }
  
  protected static function buildStatusImageMap() {
    $image_pass = [
      '#theme' => 'image',
      '#uri' => 'core/misc/icons/73b355/check.svg',
      '#width' => 18,
      '#height' => 18,
      '#alt' => 'Pass',
    ];
    $image_fail = [
      '#theme' => 'image',
      '#uri' => 'core/misc/icons/e32700/error.svg',
      '#width' => 18,
      '#height' => 18,
      '#alt' => 'Fail',
    ];
    $image_exception = [
      '#theme' => 'image',
      '#uri' => 'core/misc/icons/e29700/warning.svg',
      '#width' => 18,
      '#height' => 18,
      '#alt' => 'Exception',
    ];
    $image_debug = [
      '#theme' => 'image',
      '#uri' => 'core/misc/icons/e29700/warning.svg',
      '#width' => 18,
      '#height' => 18,
      '#alt' => 'Debug',
    ];
    return [
      'pass' => $image_pass,
      'fail' => $image_fail,
      'exception' => $image_exception,
      'debug' => $image_debug,
    ];
  }
  
  public function getFormId() {
    return 'simpletest_results_form';
  }
  
  public function buildForm(array $form, FormStateInterface $form_state, $test_id = NULL) {
    
    $results = [];
    if (is_numeric($test_id) && !($results = $this
      ->getResults($test_id))) {
      $this
        ->messenger()
        ->addError($this
        ->t('No test results to display.'));
      return $this
        ->redirect('simpletest.test_form');
    }
    
    $form['#attached']['library'][] = 'simpletest/drupal.simpletest';
    
    $filter = static::addResultForm($form, $results, $this
      ->getStringTranslation());
    
    $form['#action'] = Url::fromRoute('simpletest.result_form', [
      'test_id' => 're-run',
    ])
      ->toString();
    $form['action'] = [
      '#type' => 'fieldset',
      '#title' => $this
        ->t('Actions'),
      '#attributes' => [
        'class' => [
          'container-inline',
        ],
      ],
      '#weight' => -11,
    ];
    $form['action']['filter'] = [
      '#type' => 'select',
      '#title' => 'Filter',
      '#options' => [
        'all' => $this
          ->t('All (@count)', [
          '@count' => count($filter['pass']) + count($filter['fail']),
        ]),
        'pass' => $this
          ->t('Pass (@count)', [
          '@count' => count($filter['pass']),
        ]),
        'fail' => $this
          ->t('Fail (@count)', [
          '@count' => count($filter['fail']),
        ]),
      ],
    ];
    $form['action']['filter']['#default_value'] = $filter['fail'] ? 'fail' : 'all';
    
    $form['action']['filter_pass'] = [
      '#type' => 'hidden',
      '#default_value' => implode(',', $filter['pass']),
    ];
    $form['action']['filter_fail'] = [
      '#type' => 'hidden',
      '#default_value' => implode(',', $filter['fail']),
    ];
    $form['action']['op'] = [
      '#type' => 'submit',
      '#value' => $this
        ->t('Run tests'),
    ];
    $form['action']['return'] = [
      '#type' => 'link',
      '#title' => $this
        ->t('Return to list'),
      '#url' => Url::fromRoute('simpletest.test_form'),
    ];
    if (is_numeric($test_id)) {
      $this->cleaner
        ->cleanResultsTable($test_id);
    }
    return $form;
  }
  
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $pass = $form_state
      ->getValue('filter_pass') ? explode(',', $form_state
      ->getValue('filter_pass')) : [];
    $fail = $form_state
      ->getValue('filter_fail') ? explode(',', $form_state
      ->getValue('filter_fail')) : [];
    if ($form_state
      ->getValue('filter') == 'all') {
      $classes = array_merge($pass, $fail);
    }
    elseif ($form_state
      ->getValue('filter') == 'pass') {
      $classes = $pass;
    }
    else {
      $classes = $fail;
    }
    if (!$classes) {
      $form_state
        ->setRedirect('simpletest.test_form');
      return;
    }
    $form_execute = [];
    $form_state_execute = new FormState();
    foreach ($classes as $class) {
      $form_state_execute
        ->setValue([
        'tests',
        $class,
      ], $class);
    }
    
    $simpletest_test_form = SimpletestTestForm::create(\Drupal::getContainer());
    $simpletest_test_form
      ->buildForm($form_execute, $form_state_execute);
    $simpletest_test_form
      ->submitForm($form_execute, $form_state_execute);
    if ($redirect = $form_state_execute
      ->getRedirect()) {
      $form_state
        ->setRedirectUrl($redirect);
    }
  }
  
  protected function getResults($test_id) {
    return $this->database
      ->select('simpletest')
      ->fields('simpletest')
      ->condition('test_id', $test_id)
      ->orderBy('test_class')
      ->orderBy('message_id')
      ->execute()
      ->fetchAll();
  }
  
  public static function addResultForm(array &$form, array $results) {
    
    $test_results = [];
    foreach ($results as $result) {
      if (!isset($test_results[$result->test_class])) {
        $test_results[$result->test_class] = [];
      }
      $test_results[$result->test_class][] = $result;
    }
    $image_status_map = static::buildStatusImageMap();
    
    $filter = [
      'pass' => [],
      'fail' => [],
    ];
    
    $form['result'] = [
      '#type' => 'fieldset',
      '#title' => 'Results',
      
      '#attributes' => [],
    ];
    $form['result']['summary'] = $summary = [
      '#theme' => 'simpletest_result_summary',
      '#pass' => 0,
      '#fail' => 0,
      '#exception' => 0,
      '#debug' => 0,
    ];
    \Drupal::service('test_discovery')
      ->registerTestNamespaces();
    
    $header = [
      'Message',
      'Group',
      'Filename',
      'Line',
      'Function',
      [
        'colspan' => 2,
        'data' => 'Status',
      ],
    ];
    $form['result']['results'] = [];
    foreach ($test_results as $group => $assertions) {
      
      $info = TestDiscovery::getTestInfo($group);
      $form['result']['results'][$group] = [
        '#type' => 'details',
        '#title' => $info['name'],
        '#open' => TRUE,
        '#description' => $info['description'],
      ];
      $form['result']['results'][$group]['summary'] = $summary;
      $group_summary =& $form['result']['results'][$group]['summary'];
      
      $rows = [];
      foreach ($assertions as $assertion) {
        $row = [];
        $row[] = [
          'data' => [
            '#markup' => $assertion->message,
          ],
        ];
        $row[] = $assertion->message_group;
        $row[] = \Drupal::service('file_system')
          ->basename($assertion->file);
        $row[] = $assertion->line;
        $row[] = $assertion->function;
        $row[] = [
          'data' => $image_status_map[$assertion->status],
        ];
        $class = 'simpletest-' . $assertion->status;
        if ($assertion->message_group == 'Debug') {
          $class = 'simpletest-debug';
        }
        $rows[] = [
          'data' => $row,
          'class' => [
            $class,
          ],
        ];
        $group_summary['#' . $assertion->status]++;
        $form['result']['summary']['#' . $assertion->status]++;
      }
      $form['result']['results'][$group]['table'] = [
        '#type' => 'table',
        '#header' => $header,
        '#rows' => $rows,
      ];
      
      $group_summary['#ok'] = $group_summary['#fail'] + $group_summary['#exception'] == 0;
      $form['result']['results'][$group]['#open'] = !$group_summary['#ok'];
      
      $filter[$group_summary['#ok'] ? 'pass' : 'fail'][] = $group;
    }
    
    $form['result']['summary']['#ok'] = $form['result']['summary']['#fail'] + $form['result']['summary']['#exception'] == 0;
    return $filter;
  }
}