comparison core/scripts/run-tests.sh @ 14:1fec387a4317

Update Drupal core to 8.5.2 via Composer
author Chris Cannam
date Mon, 23 Apr 2018 09:46:53 +0100
parents 7a779792577d
children c2387f117808
comparison
equal deleted inserted replaced
13:5fb285c0d0e3 14:1fec387a4317
7 7
8 use Drupal\Component\FileSystem\FileSystem; 8 use Drupal\Component\FileSystem\FileSystem;
9 use Drupal\Component\Utility\Html; 9 use Drupal\Component\Utility\Html;
10 use Drupal\Component\Utility\Timer; 10 use Drupal\Component\Utility\Timer;
11 use Drupal\Component\Uuid\Php; 11 use Drupal\Component\Uuid\Php;
12 use Drupal\Core\Composer\Composer;
13 use Drupal\Core\Asset\AttachedAssets;
12 use Drupal\Core\Database\Database; 14 use Drupal\Core\Database\Database;
13 use Drupal\Core\Site\Settings;
14 use Drupal\Core\StreamWrapper\PublicStream; 15 use Drupal\Core\StreamWrapper\PublicStream;
15 use Drupal\Core\Test\TestDatabase; 16 use Drupal\Core\Test\TestDatabase;
16 use Drupal\Core\Test\TestRunnerKernel; 17 use Drupal\Core\Test\TestRunnerKernel;
17 use Drupal\simpletest\Form\SimpletestResultsForm; 18 use Drupal\simpletest\Form\SimpletestResultsForm;
18 use Drupal\simpletest\TestBase; 19 use Drupal\simpletest\TestBase;
19 use Drupal\simpletest\TestDiscovery; 20 use Drupal\simpletest\TestDiscovery;
20 use PHPUnit\Framework\TestCase; 21 use PHPUnit\Framework\TestCase;
22 use PHPUnit\Runner\Version;
21 use Symfony\Component\HttpFoundation\Request; 23 use Symfony\Component\HttpFoundation\Request;
22
23 $autoloader = require_once __DIR__ . '/../../autoload.php';
24 24
25 // Define some colors for display. 25 // Define some colors for display.
26 // A nice calming green. 26 // A nice calming green.
27 const SIMPLETEST_SCRIPT_COLOR_PASS = 32; 27 const SIMPLETEST_SCRIPT_COLOR_PASS = 32;
28 // An alerting Red. 28 // An alerting Red.
35 35
36 const SIMPLETEST_SCRIPT_EXIT_SUCCESS = 0; 36 const SIMPLETEST_SCRIPT_EXIT_SUCCESS = 0;
37 const SIMPLETEST_SCRIPT_EXIT_FAILURE = 1; 37 const SIMPLETEST_SCRIPT_EXIT_FAILURE = 1;
38 const SIMPLETEST_SCRIPT_EXIT_EXCEPTION = 2; 38 const SIMPLETEST_SCRIPT_EXIT_EXCEPTION = 2;
39 39
40 // Set defaults and get overrides.
41 list($args, $count) = simpletest_script_parse_args();
42
43 if ($args['help'] || $count == 0) {
44 simpletest_script_help();
45 exit(($count == 0) ? SIMPLETEST_SCRIPT_EXIT_FAILURE : SIMPLETEST_SCRIPT_EXIT_SUCCESS);
46 }
47
48 simpletest_script_init();
49
40 if (!class_exists(TestCase::class)) { 50 if (!class_exists(TestCase::class)) {
41 echo "\nrun-tests.sh requires the PHPUnit testing framework. Please use 'composer install --dev' to ensure that it is present.\n\n"; 51 echo "\nrun-tests.sh requires the PHPUnit testing framework. Please use 'composer install --dev' to ensure that it is present.\n\n";
42 exit(SIMPLETEST_SCRIPT_EXIT_FAILURE); 52 exit(SIMPLETEST_SCRIPT_EXIT_FAILURE);
43 }
44
45 // Set defaults and get overrides.
46 list($args, $count) = simpletest_script_parse_args();
47
48 if ($args['help'] || $count == 0) {
49 simpletest_script_help();
50 exit(($count == 0) ? SIMPLETEST_SCRIPT_EXIT_FAILURE : SIMPLETEST_SCRIPT_EXIT_SUCCESS);
51 }
52
53 simpletest_script_init();
54
55 try {
56 $request = Request::createFromGlobals();
57 $kernel = TestRunnerKernel::createFromRequest($request, $autoloader);
58 $kernel->prepareLegacyRequest($request);
59 }
60 catch (Exception $e) {
61 echo (string) $e;
62 exit(SIMPLETEST_SCRIPT_EXIT_EXCEPTION);
63 } 53 }
64 54
65 if ($args['execute-test']) { 55 if ($args['execute-test']) {
66 simpletest_script_setup_database(); 56 simpletest_script_setup_database();
67 simpletest_script_run_one_test($args['test-id'], $args['execute-test']); 57 simpletest_script_run_one_test($args['test-id'], $args['execute-test']);
96 if ($args['list-files'] || $args['list-files-json']) { 86 if ($args['list-files'] || $args['list-files-json']) {
97 // List all files which could be run as tests. 87 // List all files which could be run as tests.
98 $test_discovery = NULL; 88 $test_discovery = NULL;
99 try { 89 try {
100 $test_discovery = \Drupal::service('test_discovery'); 90 $test_discovery = \Drupal::service('test_discovery');
101 } catch (Exception $e) { 91 }
92 catch (Exception $e) {
102 error_log((string) $e); 93 error_log((string) $e);
103 echo (string)$e; 94 echo (string) $e;
104 exit(SIMPLETEST_SCRIPT_EXIT_EXCEPTION); 95 exit(SIMPLETEST_SCRIPT_EXIT_EXCEPTION);
105 } 96 }
106 // TestDiscovery::findAllClassFiles() gives us a classmap similar to a 97 // TestDiscovery::findAllClassFiles() gives us a classmap similar to a
107 // Composer 'classmap' array. 98 // Composer 'classmap' array.
108 $test_classes = $test_discovery->findAllClassFiles(); 99 $test_classes = $test_discovery->findAllClassFiles();
111 echo json_encode($test_classes); 102 echo json_encode($test_classes);
112 exit(SIMPLETEST_SCRIPT_EXIT_SUCCESS); 103 exit(SIMPLETEST_SCRIPT_EXIT_SUCCESS);
113 } 104 }
114 // Output the list of files. 105 // Output the list of files.
115 else { 106 else {
116 foreach(array_values($test_classes) as $test_class) { 107 foreach (array_values($test_classes) as $test_class) {
117 echo $test_class . "\n"; 108 echo $test_class . "\n";
118 } 109 }
119 } 110 }
120 exit(SIMPLETEST_SCRIPT_EXIT_SUCCESS); 111 exit(SIMPLETEST_SCRIPT_EXIT_SUCCESS);
121 } 112 }
139 echo " - " . $text . "\n"; 130 echo " - " . $text . "\n";
140 } 131 }
141 exit(SIMPLETEST_SCRIPT_EXIT_SUCCESS); 132 exit(SIMPLETEST_SCRIPT_EXIT_SUCCESS);
142 } 133 }
143 134
135 // Ensure we have the correct PHPUnit version for the version of PHP.
136 if (class_exists('\PHPUnit_Runner_Version')) {
137 $phpunit_version = \PHPUnit_Runner_Version::id();
138 }
139 else {
140 $phpunit_version = Version::id();
141 }
142 if (!Composer::upgradePHPUnitCheck($phpunit_version)) {
143 simpletest_script_print_error("PHPUnit testing framework version 6 or greater is required when running on PHP 7.2 or greater. Run the command 'composer run-script drupal-phpunit-upgrade' in order to fix this.");
144 exit(SIMPLETEST_SCRIPT_EXIT_FAILURE);
145 }
146
144 $test_list = simpletest_script_get_test_list(); 147 $test_list = simpletest_script_get_test_list();
145 148
146 // Try to allocate unlimited time to run the tests. 149 // Try to allocate unlimited time to run the tests.
147 drupal_set_time_limit(0); 150 drupal_set_time_limit(0);
148 simpletest_script_reporter_init(); 151 simpletest_script_reporter_init();
149 152
150 $tests_to_run = array(); 153 $tests_to_run = [];
151 for ($i = 0; $i < $args['repeat']; $i++) { 154 for ($i = 0; $i < $args['repeat']; $i++) {
152 $tests_to_run = array_merge($tests_to_run, $test_list); 155 $tests_to_run = array_merge($tests_to_run, $test_list);
153 } 156 }
154 157
155 // Execute tests. 158 // Execute tests.
346 * @return array 349 * @return array
347 * The list of arguments. 350 * The list of arguments.
348 */ 351 */
349 function simpletest_script_parse_args() { 352 function simpletest_script_parse_args() {
350 // Set default values. 353 // Set default values.
351 $args = array( 354 $args = [
352 'script' => '', 355 'script' => '',
353 'help' => FALSE, 356 'help' => FALSE,
354 'list' => FALSE, 357 'list' => FALSE,
355 'list-files' => FALSE, 358 'list-files' => FALSE,
356 'list-files-json' => FALSE, 359 'list-files-json' => FALSE,
368 'directory' => NULL, 371 'directory' => NULL,
369 'color' => FALSE, 372 'color' => FALSE,
370 'verbose' => FALSE, 373 'verbose' => FALSE,
371 'keep-results' => FALSE, 374 'keep-results' => FALSE,
372 'keep-results-table' => FALSE, 375 'keep-results-table' => FALSE,
373 'test_names' => array(), 376 'test_names' => [],
374 'repeat' => 1, 377 'repeat' => 1,
375 'die-on-fail' => FALSE, 378 'die-on-fail' => FALSE,
376 'suppress-deprecations' => FALSE, 379 'suppress-deprecations' => FALSE,
377 'browser' => FALSE, 380 'browser' => FALSE,
378 // Used internally. 381 // Used internally.
379 'test-id' => 0, 382 'test-id' => 0,
380 'execute-test' => '', 383 'execute-test' => '',
381 'xml' => '', 384 'xml' => '',
382 'non-html' => FALSE, 385 'non-html' => FALSE,
383 ); 386 ];
384 387
385 // Override with set values. 388 // Override with set values.
386 $args['script'] = basename(array_shift($_SERVER['argv'])); 389 $args['script'] = basename(array_shift($_SERVER['argv']));
387 390
388 $count = 0; 391 $count = 0;
401 } 404 }
402 else { 405 else {
403 $args[$matches[1]] = array_shift($_SERVER['argv']); 406 $args[$matches[1]] = array_shift($_SERVER['argv']);
404 } 407 }
405 // Clear extraneous values. 408 // Clear extraneous values.
406 $args['test_names'] = array(); 409 $args['test_names'] = [];
407 $count++; 410 $count++;
408 } 411 }
409 else { 412 else {
410 // Argument not found in list. 413 // Argument not found in list.
411 simpletest_script_print_error("Unknown argument '$arg'."); 414 simpletest_script_print_error("Unknown argument '$arg'.");
426 } 429 }
427 430
428 if ($args['browser']) { 431 if ($args['browser']) {
429 $args['keep-results'] = TRUE; 432 $args['keep-results'] = TRUE;
430 } 433 }
431 return array($args, $count); 434 return [$args, $count];
432 } 435 }
433 436
434 /** 437 /**
435 * Initialize script variables and perform general setup requirements. 438 * Initialize script variables and perform general setup requirements.
436 */ 439 */
459 else { 462 else {
460 simpletest_script_print_error('Unable to automatically determine the path to the PHP interpreter. Supply the --php command line argument.'); 463 simpletest_script_print_error('Unable to automatically determine the path to the PHP interpreter. Supply the --php command line argument.');
461 simpletest_script_help(); 464 simpletest_script_help();
462 exit(SIMPLETEST_SCRIPT_EXIT_FAILURE); 465 exit(SIMPLETEST_SCRIPT_EXIT_FAILURE);
463 } 466 }
467
468 // Detect if we're in the top-level process using the private 'execute-test'
469 // argument. Determine if being run on drupal.org's testing infrastructure
470 // using the presence of 'drupaltestbot' in the database url.
471 // @todo https://www.drupal.org/project/drupalci_testbot/issues/2860941 Use
472 // better environment variable to detect DrupalCI.
473 // @todo https://www.drupal.org/project/drupal/issues/2942473 Remove when
474 // dropping PHPUnit 4 and PHP 5 support.
475 if (!$args['execute-test'] && preg_match('/drupalci/', $args['sqlite'])) {
476 // Update PHPUnit if needed and possible. There is a later check once the
477 // autoloader is in place to ensure we're on the correct version. We need to
478 // do this before the autoloader is in place to ensure that it is correct.
479 $composer = ($composer = rtrim('\\' === DIRECTORY_SEPARATOR ? preg_replace('/[\r\n].*/', '', `where.exe composer.phar`) : `which composer.phar`))
480 ? $php . ' ' . escapeshellarg($composer)
481 : 'composer';
482 passthru("$composer run-script drupal-phpunit-upgrade-check");
483 }
484
485 $autoloader = require_once __DIR__ . '/../../autoload.php';
464 486
465 // Get URL from arguments. 487 // Get URL from arguments.
466 if (!empty($args['url'])) { 488 if (!empty($args['url'])) {
467 $parsed_url = parse_url($args['url']); 489 $parsed_url = parse_url($args['url']);
468 $host = $parsed_url['host'] . (isset($parsed_url['port']) ? ':' . $parsed_url['port'] : ''); 490 $host = $parsed_url['host'] . (isset($parsed_url['port']) ? ':' . $parsed_url['port'] : '');
518 $_SERVER[$key] = str_replace('http://', 'https://', $_SERVER[$key]); 540 $_SERVER[$key] = str_replace('http://', 'https://', $_SERVER[$key]);
519 } 541 }
520 } 542 }
521 543
522 chdir(realpath(__DIR__ . '/../..')); 544 chdir(realpath(__DIR__ . '/../..'));
545
546 // Prepare the kernel.
547 try {
548 $request = Request::createFromGlobals();
549 $kernel = TestRunnerKernel::createFromRequest($request, $autoloader);
550 $kernel->prepareLegacyRequest($request);
551 }
552 catch (Exception $e) {
553 echo (string) $e;
554 exit(SIMPLETEST_SCRIPT_EXIT_EXCEPTION);
555 }
523 } 556 }
524 557
525 /** 558 /**
526 * Sets up database connection info for running tests. 559 * Sets up database connection info for running tests.
527 * 560 *
594 $sqlite = $args['sqlite']; 627 $sqlite = $args['sqlite'];
595 } 628 }
596 else { 629 else {
597 $sqlite = DRUPAL_ROOT . '/' . $args['sqlite']; 630 $sqlite = DRUPAL_ROOT . '/' . $args['sqlite'];
598 } 631 }
599 $databases['test-runner']['default'] = array( 632 $databases['test-runner']['default'] = [
600 'driver' => 'sqlite', 633 'driver' => 'sqlite',
601 'database' => $sqlite, 634 'database' => $sqlite,
602 'prefix' => array( 635 'prefix' => [
603 'default' => '', 636 'default' => '',
604 ), 637 ],
605 ); 638 ];
606 // Create the test runner SQLite database, unless it exists already. 639 // Create the test runner SQLite database, unless it exists already.
607 if ($new && !file_exists($sqlite)) { 640 if ($new && !file_exists($sqlite)) {
608 if (!is_dir(dirname($sqlite))) { 641 if (!is_dir(dirname($sqlite))) {
609 mkdir(dirname($sqlite)); 642 mkdir(dirname($sqlite));
610 } 643 }
662 global $args, $test_ids; 695 global $args, $test_ids;
663 696
664 $total_status = SIMPLETEST_SCRIPT_EXIT_SUCCESS; 697 $total_status = SIMPLETEST_SCRIPT_EXIT_SUCCESS;
665 698
666 // Multi-process execution. 699 // Multi-process execution.
667 $children = array(); 700 $children = [];
668 while (!empty($test_classes) || !empty($children)) { 701 while (!empty($test_classes) || !empty($children)) {
669 while (count($children) < $args['concurrency']) { 702 while (count($children) < $args['concurrency']) {
670 if (empty($test_classes)) { 703 if (empty($test_classes)) {
671 break; 704 break;
672 } 705 }
673 706
674 try { 707 try {
675 $test_id = Database::getConnection('default', 'test-runner') 708 $test_id = Database::getConnection('default', 'test-runner')
676 ->insert('simpletest_test_id') 709 ->insert('simpletest_test_id')
677 ->useDefaults(array('test_id')) 710 ->useDefaults(['test_id'])
678 ->execute(); 711 ->execute();
679 } 712 }
680 catch (Exception $e) { 713 catch (Exception $e) {
681 echo (string) $e; 714 echo (string) $e;
682 exit(SIMPLETEST_SCRIPT_EXIT_EXCEPTION); 715 exit(SIMPLETEST_SCRIPT_EXIT_EXCEPTION);
684 $test_ids[] = $test_id; 717 $test_ids[] = $test_id;
685 718
686 $test_class = array_shift($test_classes); 719 $test_class = array_shift($test_classes);
687 // Fork a child process. 720 // Fork a child process.
688 $command = simpletest_script_command($test_id, $test_class); 721 $command = simpletest_script_command($test_id, $test_class);
689 $process = proc_open($command, array(), $pipes, NULL, NULL, array('bypass_shell' => TRUE)); 722 $process = proc_open($command, [], $pipes, NULL, NULL, ['bypass_shell' => TRUE]);
690 723
691 if (!is_resource($process)) { 724 if (!is_resource($process)) {
692 echo "Unable to fork test process. Aborting.\n"; 725 echo "Unable to fork test process. Aborting.\n";
693 exit(SIMPLETEST_SCRIPT_EXIT_SUCCESS); 726 exit(SIMPLETEST_SCRIPT_EXIT_SUCCESS);
694 } 727 }
695 728
696 // Register our new child. 729 // Register our new child.
697 $children[] = array( 730 $children[] = [
698 'process' => $process, 731 'process' => $process,
699 'test_id' => $test_id, 732 'test_id' => $test_id,
700 'class' => $test_class, 733 'class' => $test_class,
701 'pipes' => $pipes, 734 'pipes' => $pipes,
702 ); 735 ];
703 } 736 }
704 737
705 // Wait for children every 200ms. 738 // Wait for children every 200ms.
706 usleep(200000); 739 usleep(200000);
707 740
758 $reflection = new \ReflectionClass($class); 791 $reflection = new \ReflectionClass($class);
759 if ($reflection->hasProperty('runLimit')) { 792 if ($reflection->hasProperty('runLimit')) {
760 set_time_limit($reflection->getStaticPropertyValue('runLimit')); 793 set_time_limit($reflection->getStaticPropertyValue('runLimit'));
761 } 794 }
762 795
763 $results = simpletest_run_phpunit_tests($test_id, array($class), $status); 796 $results = simpletest_run_phpunit_tests($test_id, [$class], $status);
764 simpletest_process_phpunit_results($results); 797 simpletest_process_phpunit_results($results);
765 798
766 // Map phpunit results to a data structure we can pass to 799 // Map phpunit results to a data structure we can pass to
767 // _simpletest_format_summary_line. 800 // _simpletest_format_summary_line.
768 $summaries = simpletest_summarize_phpunit_result($results); 801 $summaries = simpletest_summarize_phpunit_result($results);
784 $methods = [$method]; 817 $methods = [$method];
785 } 818 }
786 else { 819 else {
787 $class_name = $test_class; 820 $class_name = $test_class;
788 // Use empty array to run all the test methods. 821 // Use empty array to run all the test methods.
789 $methods = array(); 822 $methods = [];
790 } 823 }
791 $test = new $class_name($test_id); 824 $test = new $class_name($test_id);
792 if ($args['suppress-deprecations']) { 825 if ($args['suppress-deprecations']) {
793 putenv('SYMFONY_DEPRECATIONS_HELPER=disabled'); 826 putenv('SYMFONY_DEPRECATIONS_HELPER=disabled');
794 } 827 }
795 else { 828 else {
796 putenv('SYMFONY_DEPRECATIONS_HELPER=strict'); 829 // Prevent deprecations caused by vendor code calling deprecated code.
830 // This also prevents mock objects in PHPUnit 6 triggering silenced
831 // deprecations from breaking the test suite. We should consider changing
832 // this to 'strict' once PHPUnit 4 is no longer used.
833 putenv('SYMFONY_DEPRECATIONS_HELPER=weak_vendors');
797 } 834 }
798 if (is_subclass_of($test_class, TestCase::class)) { 835 if (is_subclass_of($test_class, TestCase::class)) {
799 $status = simpletest_script_run_phpunit($test_id, $test_class); 836 $status = simpletest_script_run_phpunit($test_id, $test_class);
800 } 837 }
801 else { 838 else {
843 if (!empty($args['dburl'])) { 880 if (!empty($args['dburl'])) {
844 $command .= ' --dburl ' . escapeshellarg($args['dburl']); 881 $command .= ' --dburl ' . escapeshellarg($args['dburl']);
845 } 882 }
846 $command .= ' --php ' . escapeshellarg($php); 883 $command .= ' --php ' . escapeshellarg($php);
847 $command .= " --test-id $test_id"; 884 $command .= " --test-id $test_id";
848 foreach (array('verbose', 'keep-results', 'color', 'die-on-fail', 'suppress-deprecations') as $arg) { 885 foreach (['verbose', 'keep-results', 'color', 'die-on-fail', 'suppress-deprecations'] as $arg) {
849 if ($args[$arg]) { 886 if ($args[$arg]) {
850 $command .= ' --' . $arg; 887 $command .= ' --' . $arg;
851 } 888 }
852 } 889 }
853 // --execute-test and class name needs to come last. 890 // --execute-test and class name needs to come last.
896 return; 933 return;
897 } 934 }
898 935
899 // Do not output verbose cleanup messages in case of a positive exitcode. 936 // Do not output verbose cleanup messages in case of a positive exitcode.
900 $output = !empty($exitcode); 937 $output = !empty($exitcode);
901 $messages = array(); 938 $messages = [];
902 939
903 $messages[] = "- Found database prefix '$db_prefix' for test ID $test_id."; 940 $messages[] = "- Found database prefix '$db_prefix' for test ID $test_id.";
904 941
905 // Read the log file in case any fatal errors caused the test to crash. 942 // Read the log file in case any fatal errors caused the test to crash.
906 try { 943 try {
925 } 962 }
926 // Delete the test site directory. 963 // Delete the test site directory.
927 // simpletest_clean_temporary_directories() cannot be used here, since it 964 // simpletest_clean_temporary_directories() cannot be used here, since it
928 // would also delete file directories of other tests that are potentially 965 // would also delete file directories of other tests that are potentially
929 // running concurrently. 966 // running concurrently.
930 file_unmanaged_delete_recursive($test_directory, array('Drupal\simpletest\TestBase', 'filePreDeleteCallback')); 967 file_unmanaged_delete_recursive($test_directory, ['Drupal\simpletest\TestBase', 'filePreDeleteCallback']);
931 $messages[] = "- Removed test site directory."; 968 $messages[] = "- Removed test site directory.";
932 } 969 }
933 970
934 // Clear out all database tables from the test. 971 // Clear out all database tables from the test.
935 try { 972 try {
966 */ 1003 */
967 function simpletest_script_get_test_list() { 1004 function simpletest_script_get_test_list() {
968 global $args; 1005 global $args;
969 1006
970 $types_processed = empty($args['types']); 1007 $types_processed = empty($args['types']);
971 $test_list = array(); 1008 $test_list = [];
972 if ($args['all'] || $args['module']) { 1009 if ($args['all'] || $args['module']) {
973 try { 1010 try {
974 $groups = simpletest_test_get_all($args['module'], $args['types']); 1011 $groups = simpletest_test_get_all($args['module'], $args['types']);
975 $types_processed = TRUE; 1012 $types_processed = TRUE;
976 } 1013 }
977 catch (Exception $e) { 1014 catch (Exception $e) {
978 echo (string) $e; 1015 echo (string) $e;
979 exit(SIMPLETEST_SCRIPT_EXIT_EXCEPTION); 1016 exit(SIMPLETEST_SCRIPT_EXIT_EXCEPTION);
980 } 1017 }
981 $all_tests = array(); 1018 $all_tests = [];
982 foreach ($groups as $group => $tests) { 1019 foreach ($groups as $group => $tests) {
983 $all_tests = array_merge($all_tests, array_keys($tests)); 1020 $all_tests = array_merge($all_tests, array_keys($tests));
984 } 1021 }
985 $test_list = $all_tests; 1022 $test_list = $all_tests;
986 } 1023 }
987 else { 1024 else {
988 if ($args['class']) { 1025 if ($args['class']) {
989 $test_list = array(); 1026 $test_list = [];
990 foreach ($args['test_names'] as $test_class) { 1027 foreach ($args['test_names'] as $test_class) {
991 list($class_name) = explode('::', $test_class, 2); 1028 list($class_name) = explode('::', $test_class, 2);
992 if (class_exists($class_name)) { 1029 if (class_exists($class_name)) {
993 $test_list[] = $test_class; 1030 $test_list[] = $test_class;
994 } 1031 }
998 } 1035 }
999 catch (Exception $e) { 1036 catch (Exception $e) {
1000 echo (string) $e; 1037 echo (string) $e;
1001 exit(SIMPLETEST_SCRIPT_EXIT_EXCEPTION); 1038 exit(SIMPLETEST_SCRIPT_EXIT_EXCEPTION);
1002 } 1039 }
1003 $all_classes = array(); 1040 $all_classes = [];
1004 foreach ($groups as $group) { 1041 foreach ($groups as $group) {
1005 $all_classes = array_merge($all_classes, array_keys($group)); 1042 $all_classes = array_merge($all_classes, array_keys($group));
1006 } 1043 }
1007 simpletest_script_print_error('Test class not found: ' . $class_name); 1044 simpletest_script_print_error('Test class not found: ' . $class_name);
1008 simpletest_script_print_alternatives($class_name, $all_classes, 6); 1045 simpletest_script_print_alternatives($class_name, $all_classes, 6);
1045 // Since we do not want to hard-code too many structural file/directory 1082 // Since we do not want to hard-code too many structural file/directory
1046 // assumptions about PSR-0/4 files and directories, we check for the 1083 // assumptions about PSR-0/4 files and directories, we check for the
1047 // minimal conditions only; i.e., a '*.php' file that has '/Tests/' in 1084 // minimal conditions only; i.e., a '*.php' file that has '/Tests/' in
1048 // its path. 1085 // its path.
1049 // Ignore anything from third party vendors. 1086 // Ignore anything from third party vendors.
1050 $ignore = array('.', '..', 'vendor'); 1087 $ignore = ['.', '..', 'vendor'];
1051 $files = []; 1088 $files = [];
1052 if ($args['directory'][0] === '/') { 1089 if ($args['directory'][0] === '/') {
1053 $directory = $args['directory']; 1090 $directory = $args['directory'];
1054 } 1091 }
1055 else { 1092 else {
1135 * Initialize the reporter. 1172 * Initialize the reporter.
1136 */ 1173 */
1137 function simpletest_script_reporter_init() { 1174 function simpletest_script_reporter_init() {
1138 global $args, $test_list, $results_map; 1175 global $args, $test_list, $results_map;
1139 1176
1140 $results_map = array( 1177 $results_map = [
1141 'pass' => 'Pass', 1178 'pass' => 'Pass',
1142 'fail' => 'Fail', 1179 'fail' => 'Fail',
1143 'exception' => 'Exception', 1180 'exception' => 'Exception',
1144 ); 1181 ];
1145 1182
1146 echo "\n"; 1183 echo "\n";
1147 echo "Drupal test run\n"; 1184 echo "Drupal test run\n";
1148 echo "---------------\n"; 1185 echo "---------------\n";
1149 echo "\n"; 1186 echo "\n";
1180 */ 1217 */
1181 function simpletest_script_reporter_display_summary($class, $results) { 1218 function simpletest_script_reporter_display_summary($class, $results) {
1182 // Output all test results vertically aligned. 1219 // Output all test results vertically aligned.
1183 // Cut off the class name after 60 chars, and pad each group with 3 digits 1220 // Cut off the class name after 60 chars, and pad each group with 3 digits
1184 // by default (more than 999 assertions are rare). 1221 // by default (more than 999 assertions are rare).
1185 $output = vsprintf('%-60.60s %10s %9s %14s %12s', array( 1222 $output = vsprintf('%-60.60s %10s %9s %14s %12s', [
1186 $class, 1223 $class,
1187 $results['#pass'] . ' passes', 1224 $results['#pass'] . ' passes',
1188 !$results['#fail'] ? '' : $results['#fail'] . ' fails', 1225 !$results['#fail'] ? '' : $results['#fail'] . ' fails',
1189 !$results['#exception'] ? '' : $results['#exception'] . ' exceptions', 1226 !$results['#exception'] ? '' : $results['#exception'] . ' exceptions',
1190 !$results['#debug'] ? '' : $results['#debug'] . ' messages', 1227 !$results['#debug'] ? '' : $results['#debug'] . ' messages',
1191 )); 1228 ]);
1192 1229
1193 $status = ($results['#fail'] || $results['#exception'] ? 'fail' : 'pass'); 1230 $status = ($results['#fail'] || $results['#exception'] ? 'fail' : 'pass');
1194 simpletest_script_print($output . "\n", simpletest_script_color_code($status)); 1231 simpletest_script_print($output . "\n", simpletest_script_color_code($status));
1195 } 1232 }
1196 1233
1207 echo (string) $e; 1244 echo (string) $e;
1208 exit(SIMPLETEST_SCRIPT_EXIT_EXCEPTION); 1245 exit(SIMPLETEST_SCRIPT_EXIT_EXCEPTION);
1209 } 1246 }
1210 1247
1211 $test_class = ''; 1248 $test_class = '';
1212 $xml_files = array(); 1249 $xml_files = [];
1213 1250
1214 foreach ($results as $result) { 1251 foreach ($results as $result) {
1215 if (isset($results_map[$result->status])) { 1252 if (isset($results_map[$result->status])) {
1216 if ($result->test_class != $test_class) { 1253 if ($result->test_class != $test_class) {
1217 // We've moved onto a new class, so write the last classes results to a 1254 // We've moved onto a new class, so write the last classes results to a
1223 $test_class = $result->test_class; 1260 $test_class = $result->test_class;
1224 if (!isset($xml_files[$test_class])) { 1261 if (!isset($xml_files[$test_class])) {
1225 $doc = new DomDocument('1.0'); 1262 $doc = new DomDocument('1.0');
1226 $root = $doc->createElement('testsuite'); 1263 $root = $doc->createElement('testsuite');
1227 $root = $doc->appendChild($root); 1264 $root = $doc->appendChild($root);
1228 $xml_files[$test_class] = array('doc' => $doc, 'suite' => $root); 1265 $xml_files[$test_class] = ['doc' => $doc, 'suite' => $root];
1229 } 1266 }
1230 } 1267 }
1231 1268
1232 // For convenience: 1269 // For convenience:
1233 $dom_document = &$xml_files[$test_class]['doc']; 1270 $dom_document = &$xml_files[$test_class]['doc'];
1418 * The matching strictness. Higher values return fewer matches. A value of 1455 * The matching strictness. Higher values return fewer matches. A value of
1419 * 4 means that the function will return strings from $array if the candidate 1456 * 4 means that the function will return strings from $array if the candidate
1420 * string in $array would be identical to $string by changing 1/4 or fewer of 1457 * string in $array would be identical to $string by changing 1/4 or fewer of
1421 * its characters. 1458 * its characters.
1422 * 1459 *
1423 * @see http://php.net/manual/en/function.levenshtein.php 1460 * @see http://php.net/manual/function.levenshtein.php
1424 */ 1461 */
1425 function simpletest_script_print_alternatives($string, $array, $degree = 4) { 1462 function simpletest_script_print_alternatives($string, $array, $degree = 4) {
1426 $alternatives = array(); 1463 $alternatives = [];
1427 foreach ($array as $item) { 1464 foreach ($array as $item) {
1428 $lev = levenshtein($string, $item); 1465 $lev = levenshtein($string, $item);
1429 if ($lev <= strlen($item) / $degree || FALSE !== strpos($string, $item)) { 1466 if ($lev <= strlen($item) / $degree || FALSE !== strpos($string, $item)) {
1430 $alternatives[] = $item; 1467 $alternatives[] = $item;
1431 } 1468 }
1449 * @return array 1486 * @return array
1450 * Array of simpletest messages from the database. 1487 * Array of simpletest messages from the database.
1451 */ 1488 */
1452 function simpletest_script_load_messages_by_test_id($test_ids) { 1489 function simpletest_script_load_messages_by_test_id($test_ids) {
1453 global $args; 1490 global $args;
1454 $results = array(); 1491 $results = [];
1455 1492
1456 // Sqlite has a maximum number of variables per query. If required, the 1493 // Sqlite has a maximum number of variables per query. If required, the
1457 // database query is split into chunks. 1494 // database query is split into chunks.
1458 if (count($test_ids) > SIMPLETEST_SCRIPT_SQLITE_VARIABLE_LIMIT && !empty($args['sqlite'])) { 1495 if (count($test_ids) > SIMPLETEST_SCRIPT_SQLITE_VARIABLE_LIMIT && !empty($args['sqlite'])) {
1459 $test_id_chunks = array_chunk($test_ids, SIMPLETEST_SCRIPT_SQLITE_VARIABLE_LIMIT); 1496 $test_id_chunks = array_chunk($test_ids, SIMPLETEST_SCRIPT_SQLITE_VARIABLE_LIMIT);
1460 } 1497 }
1461 else { 1498 else {
1462 $test_id_chunks = array($test_ids); 1499 $test_id_chunks = [$test_ids];
1463 } 1500 }
1464 1501
1465 foreach ($test_id_chunks as $test_id_chunk) { 1502 foreach ($test_id_chunks as $test_id_chunk) {
1466 try { 1503 try {
1467 $result_chunk = Database::getConnection('default', 'test-runner') 1504 $result_chunk = Database::getConnection('default', 'test-runner')
1468 ->query("SELECT * FROM {simpletest} WHERE test_id IN ( :test_ids[] ) ORDER BY test_class, message_id", array( 1505 ->query("SELECT * FROM {simpletest} WHERE test_id IN ( :test_ids[] ) ORDER BY test_class, message_id", [
1469 ':test_ids[]' => $test_id_chunk, 1506 ':test_ids[]' => $test_id_chunk,
1470 ))->fetchAll(); 1507 ])->fetchAll();
1471 } 1508 }
1472 catch (Exception $e) { 1509 catch (Exception $e) {
1473 echo (string) $e; 1510 echo (string) $e;
1474 exit(SIMPLETEST_SCRIPT_EXIT_EXCEPTION); 1511 exit(SIMPLETEST_SCRIPT_EXIT_EXCEPTION);
1475 } 1512 }
1501 echo (string) $e; 1538 echo (string) $e;
1502 exit(SIMPLETEST_SCRIPT_EXIT_EXCEPTION); 1539 exit(SIMPLETEST_SCRIPT_EXIT_EXCEPTION);
1503 } 1540 }
1504 1541
1505 // Get the results form. 1542 // Get the results form.
1506 $form = array(); 1543 $form = [];
1507 SimpletestResultsForm::addResultForm($form, $results); 1544 SimpletestResultsForm::addResultForm($form, $results);
1508 1545
1509 // Get the assets to make the details element collapsible and theme the result 1546 // Get the assets to make the details element collapsible and theme the result
1510 // form. 1547 // form.
1511 $assets = new \Drupal\Core\Asset\AttachedAssets(); 1548 $assets = new AttachedAssets();
1512 $assets->setLibraries([ 1549 $assets->setLibraries([
1513 'core/drupal.collapse', 1550 'core/drupal.collapse',
1514 'system/admin', 1551 'system/admin',
1515 'simpletest/drupal.simpletest', 1552 'simpletest/drupal.simpletest',
1516 ]); 1553 ]);