Security update to Drupal 8.4.6
[yaffs-website] / web / core / tests / bootstrap.php
1 <?php
2
3 /**
4  * @file
5  * Autoloader for Drupal PHPUnit testing.
6  *
7  * @see phpunit.xml.dist
8  */
9
10 use Drupal\Component\Assertion\Handle;
11
12 /**
13  * Finds all valid extension directories recursively within a given directory.
14  *
15  * @param string $scan_directory
16  *   The directory that should be recursively scanned.
17  * @return array
18  *   An associative array of extension directories found within the scanned
19  *   directory, keyed by extension name.
20  */
21 function drupal_phpunit_find_extension_directories($scan_directory) {
22   $extensions = [];
23   $dirs = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($scan_directory, \RecursiveDirectoryIterator::FOLLOW_SYMLINKS));
24   foreach ($dirs as $dir) {
25     if (strpos($dir->getPathname(), '.info.yml') !== FALSE) {
26       // Cut off ".info.yml" from the filename for use as the extension name. We
27       // use getRealPath() so that we can scan extensions represented by
28       // directory aliases.
29       $extensions[substr($dir->getFilename(), 0, -9)] = $dir->getPathInfo()
30         ->getRealPath();
31     }
32   }
33   return $extensions;
34 }
35
36 /**
37  * Returns directories under which contributed extensions may exist.
38  *
39  * @param string $root
40  *   (optional) Path to the root of the Drupal installation.
41  *
42  * @return array
43  *   An array of directories under which contributed extensions may exist.
44  */
45 function drupal_phpunit_contrib_extension_directory_roots($root = NULL) {
46   if ($root === NULL) {
47     $root = dirname(dirname(__DIR__));
48   }
49   $paths = [
50     $root . '/core/modules',
51     $root . '/core/profiles',
52     $root . '/modules',
53     $root . '/profiles',
54     $root . '/themes',
55   ];
56   $sites_path = $root . '/sites';
57   // Note this also checks sites/../modules and sites/../profiles.
58   foreach (scandir($sites_path) as $site) {
59     if ($site[0] === '.' || $site === 'simpletest') {
60       continue;
61     }
62     $path = "$sites_path/$site";
63     $paths[] = is_dir("$path/modules") ? realpath("$path/modules") : NULL;
64     $paths[] = is_dir("$path/profiles") ? realpath("$path/profiles") : NULL;
65     $paths[] = is_dir("$path/themes") ? realpath("$path/themes") : NULL;
66   }
67   return array_filter($paths);
68 }
69
70 /**
71  * Registers the namespace for each extension directory with the autoloader.
72  *
73  * @param array $dirs
74  *   An associative array of extension directories, keyed by extension name.
75  *
76  * @return array
77  *   An associative array of extension directories, keyed by their namespace.
78  */
79 function drupal_phpunit_get_extension_namespaces($dirs) {
80   $suite_names = ['Unit', 'Kernel', 'Functional', 'FunctionalJavascript'];
81   $namespaces = [];
82   foreach ($dirs as $extension => $dir) {
83     if (is_dir($dir . '/src')) {
84       // Register the PSR-4 directory for module-provided classes.
85       $namespaces['Drupal\\' . $extension . '\\'][] = $dir . '/src';
86     }
87     $test_dir = $dir . '/tests/src';
88     if (is_dir($test_dir)) {
89       foreach ($suite_names as $suite_name) {
90         $suite_dir = $test_dir . '/' . $suite_name;
91         if (is_dir($suite_dir)) {
92           // Register the PSR-4 directory for PHPUnit-based suites.
93           $namespaces['Drupal\\Tests\\' . $extension . '\\' . $suite_name . '\\'][] = $suite_dir;
94         }
95       }
96       // Extensions can have a \Drupal\extension\Traits namespace for
97       // cross-suite trait code.
98       $trait_dir = $test_dir . '/Traits';
99       if (is_dir($trait_dir)) {
100         $namespaces['Drupal\\Tests\\' . $extension . '\\Traits\\'][] = $trait_dir;
101       }
102     }
103   }
104   return $namespaces;
105 }
106
107 // We define the COMPOSER_INSTALL constant, so that PHPUnit knows where to
108 // autoload from. This is needed for tests run in isolation mode, because
109 // phpunit.xml.dist is located in a non-default directory relative to the
110 // PHPUnit executable.
111 if (!defined('PHPUNIT_COMPOSER_INSTALL')) {
112   define('PHPUNIT_COMPOSER_INSTALL', __DIR__ . '/../../autoload.php');
113 }
114
115 /**
116  * Populate class loader with additional namespaces for tests.
117  *
118  * We run this in a function to avoid setting the class loader to a global
119  * that can change. This change can cause unpredictable false positives for
120  * phpunit's global state change watcher. The class loader can be retrieved from
121  * composer at any time by requiring autoload.php.
122  */
123 function drupal_phpunit_populate_class_loader() {
124
125   /** @var \Composer\Autoload\ClassLoader $loader */
126   $loader = require __DIR__ . '/../../autoload.php';
127
128   // Start with classes in known locations.
129   $loader->add('Drupal\\Tests', __DIR__);
130   $loader->add('Drupal\\KernelTests', __DIR__);
131   $loader->add('Drupal\\FunctionalTests', __DIR__);
132   $loader->add('Drupal\\FunctionalJavascriptTests', __DIR__);
133
134   if (!isset($GLOBALS['namespaces'])) {
135     // Scan for arbitrary extension namespaces from core and contrib.
136     $extension_roots = drupal_phpunit_contrib_extension_directory_roots();
137
138     $dirs = array_map('drupal_phpunit_find_extension_directories', $extension_roots);
139     $dirs = array_reduce($dirs, 'array_merge', []);
140     $GLOBALS['namespaces'] = drupal_phpunit_get_extension_namespaces($dirs);
141   }
142   foreach ($GLOBALS['namespaces'] as $prefix => $paths) {
143     $loader->addPsr4($prefix, $paths);
144   }
145
146   return $loader;
147 };
148
149 // Do class loader population.
150 drupal_phpunit_populate_class_loader();
151
152 // Set sane locale settings, to ensure consistent string, dates, times and
153 // numbers handling.
154 // @see \Drupal\Core\DrupalKernel::bootEnvironment()
155 setlocale(LC_ALL, 'C');
156
157 // Set the default timezone. While this doesn't cause any tests to fail, PHP
158 // complains if 'date.timezone' is not set in php.ini. The Australia/Sydney
159 // timezone is chosen so all tests are run using an edge case scenario (UTC+10
160 // and DST). This choice is made to prevent timezone related regressions and
161 // reduce the fragility of the testing system in general.
162 date_default_timezone_set('Australia/Sydney');
163
164 // Runtime assertions. PHPUnit follows the php.ini assert.active setting for
165 // runtime assertions. By default this setting is on. Here we make a call to
166 // make PHP 5 and 7 handle assertion failures the same way, but this call does
167 // not turn runtime assertions on if they weren't on already.
168 Handle::register();