Added the Search API Synonym module to deal specifically with licence and license...
[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 use Drupal\Core\Composer\Composer;
12 use PHPUnit\Runner\Version;
13
14 /**
15  * Finds all valid extension directories recursively within a given directory.
16  *
17  * @param string $scan_directory
18  *   The directory that should be recursively scanned.
19  * @return array
20  *   An associative array of extension directories found within the scanned
21  *   directory, keyed by extension name.
22  */
23 function drupal_phpunit_find_extension_directories($scan_directory) {
24   $extensions = [];
25   $dirs = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($scan_directory, \RecursiveDirectoryIterator::FOLLOW_SYMLINKS));
26   foreach ($dirs as $dir) {
27     if (strpos($dir->getPathname(), '.info.yml') !== FALSE) {
28       // Cut off ".info.yml" from the filename for use as the extension name. We
29       // use getRealPath() so that we can scan extensions represented by
30       // directory aliases.
31       $extensions[substr($dir->getFilename(), 0, -9)] = $dir->getPathInfo()
32         ->getRealPath();
33     }
34   }
35   return $extensions;
36 }
37
38 /**
39  * Returns directories under which contributed extensions may exist.
40  *
41  * @param string $root
42  *   (optional) Path to the root of the Drupal installation.
43  *
44  * @return array
45  *   An array of directories under which contributed extensions may exist.
46  */
47 function drupal_phpunit_contrib_extension_directory_roots($root = NULL) {
48   if ($root === NULL) {
49     $root = dirname(dirname(__DIR__));
50   }
51   $paths = [
52     $root . '/core/modules',
53     $root . '/core/profiles',
54     $root . '/modules',
55     $root . '/profiles',
56     $root . '/themes',
57   ];
58   $sites_path = $root . '/sites';
59   // Note this also checks sites/../modules and sites/../profiles.
60   foreach (scandir($sites_path) as $site) {
61     if ($site[0] === '.' || $site === 'simpletest') {
62       continue;
63     }
64     $path = "$sites_path/$site";
65     $paths[] = is_dir("$path/modules") ? realpath("$path/modules") : NULL;
66     $paths[] = is_dir("$path/profiles") ? realpath("$path/profiles") : NULL;
67     $paths[] = is_dir("$path/themes") ? realpath("$path/themes") : NULL;
68   }
69   return array_filter($paths, 'file_exists');
70 }
71
72 /**
73  * Registers the namespace for each extension directory with the autoloader.
74  *
75  * @param array $dirs
76  *   An associative array of extension directories, keyed by extension name.
77  *
78  * @return array
79  *   An associative array of extension directories, keyed by their namespace.
80  */
81 function drupal_phpunit_get_extension_namespaces($dirs) {
82   $suite_names = ['Unit', 'Kernel', 'Functional', 'FunctionalJavascript'];
83   $namespaces = [];
84   foreach ($dirs as $extension => $dir) {
85     if (is_dir($dir . '/src')) {
86       // Register the PSR-4 directory for module-provided classes.
87       $namespaces['Drupal\\' . $extension . '\\'][] = $dir . '/src';
88     }
89     $test_dir = $dir . '/tests/src';
90     if (is_dir($test_dir)) {
91       foreach ($suite_names as $suite_name) {
92         $suite_dir = $test_dir . '/' . $suite_name;
93         if (is_dir($suite_dir)) {
94           // Register the PSR-4 directory for PHPUnit-based suites.
95           $namespaces['Drupal\\Tests\\' . $extension . '\\' . $suite_name . '\\'][] = $suite_dir;
96         }
97       }
98       // Extensions can have a \Drupal\extension\Traits namespace for
99       // cross-suite trait code.
100       $trait_dir = $test_dir . '/Traits';
101       if (is_dir($trait_dir)) {
102         $namespaces['Drupal\\Tests\\' . $extension . '\\Traits\\'][] = $trait_dir;
103       }
104     }
105   }
106   return $namespaces;
107 }
108
109 // We define the COMPOSER_INSTALL constant, so that PHPUnit knows where to
110 // autoload from. This is needed for tests run in isolation mode, because
111 // phpunit.xml.dist is located in a non-default directory relative to the
112 // PHPUnit executable.
113 if (!defined('PHPUNIT_COMPOSER_INSTALL')) {
114   define('PHPUNIT_COMPOSER_INSTALL', __DIR__ . '/../../autoload.php');
115 }
116
117 /**
118  * Populate class loader with additional namespaces for tests.
119  *
120  * We run this in a function to avoid setting the class loader to a global
121  * that can change. This change can cause unpredictable false positives for
122  * phpunit's global state change watcher. The class loader can be retrieved from
123  * composer at any time by requiring autoload.php.
124  */
125 function drupal_phpunit_populate_class_loader() {
126
127   /** @var \Composer\Autoload\ClassLoader $loader */
128   $loader = require __DIR__ . '/../../autoload.php';
129
130   // Start with classes in known locations.
131   $loader->add('Drupal\\Tests', __DIR__);
132   $loader->add('Drupal\\TestSite', __DIR__);
133   $loader->add('Drupal\\KernelTests', __DIR__);
134   $loader->add('Drupal\\FunctionalTests', __DIR__);
135   $loader->add('Drupal\\FunctionalJavascriptTests', __DIR__);
136
137   if (!isset($GLOBALS['namespaces'])) {
138     // Scan for arbitrary extension namespaces from core and contrib.
139     $extension_roots = drupal_phpunit_contrib_extension_directory_roots();
140
141     $dirs = array_map('drupal_phpunit_find_extension_directories', $extension_roots);
142     $dirs = array_reduce($dirs, 'array_merge', []);
143     $GLOBALS['namespaces'] = drupal_phpunit_get_extension_namespaces($dirs);
144   }
145   foreach ($GLOBALS['namespaces'] as $prefix => $paths) {
146     $loader->addPsr4($prefix, $paths);
147   }
148
149   return $loader;
150 };
151
152 // Do class loader population.
153 drupal_phpunit_populate_class_loader();
154
155 // Ensure we have the correct PHPUnit version for the version of PHP.
156 if (class_exists('\PHPUnit_Runner_Version')) {
157   $phpunit_version = \PHPUnit_Runner_Version::id();
158 }
159 else {
160   $phpunit_version = Version::id();
161 }
162 if (!Composer::upgradePHPUnitCheck($phpunit_version)) {
163   $message = "PHPUnit testing framework version 6 or greater is required when running on PHP 7.0 or greater. Run the command 'composer run-script drupal-phpunit-upgrade' in order to fix this.";
164   echo "\033[31m" . $message . "\n\033[0m";
165   exit(1);
166 }
167
168 // Set sane locale settings, to ensure consistent string, dates, times and
169 // numbers handling.
170 // @see \Drupal\Core\DrupalKernel::bootEnvironment()
171 setlocale(LC_ALL, 'C');
172
173 // Set appropriate configuration for multi-byte strings.
174 mb_internal_encoding('utf-8');
175 mb_language('uni');
176
177 // Set the default timezone. While this doesn't cause any tests to fail, PHP
178 // complains if 'date.timezone' is not set in php.ini. The Australia/Sydney
179 // timezone is chosen so all tests are run using an edge case scenario (UTC+10
180 // and DST). This choice is made to prevent timezone related regressions and
181 // reduce the fragility of the testing system in general.
182 date_default_timezone_set('Australia/Sydney');
183
184 // Runtime assertions. PHPUnit follows the php.ini assert.active setting for
185 // runtime assertions. By default this setting is on. Here we make a call to
186 // make PHP 5 and 7 handle assertion failures the same way, but this call does
187 // not turn runtime assertions on if they weren't on already.
188 Handle::register();
189
190 // PHPUnit 4 to PHPUnit 6 bridge. Tests written for PHPUnit 4 need to work on
191 // PHPUnit 6 with a minimum of fuss.
192 if (version_compare($phpunit_version, '6.1', '>=')) {
193   class_alias('\PHPUnit\Framework\AssertionFailedError', '\PHPUnit_Framework_AssertionFailedError');
194   class_alias('\PHPUnit\Framework\Constraint\Count', '\PHPUnit_Framework_Constraint_Count');
195   class_alias('\PHPUnit\Framework\Error\Error', '\PHPUnit_Framework_Error');
196   class_alias('\PHPUnit\Framework\Error\Warning', '\PHPUnit_Framework_Error_Warning');
197   class_alias('\PHPUnit\Framework\ExpectationFailedException', '\PHPUnit_Framework_ExpectationFailedException');
198   class_alias('\PHPUnit\Framework\Exception', '\PHPUnit_Framework_Exception');
199   class_alias('\PHPUnit\Framework\MockObject\Matcher\InvokedRecorder', '\PHPUnit_Framework_MockObject_Matcher_InvokedRecorder');
200   class_alias('\PHPUnit\Framework\SkippedTestError', '\PHPUnit_Framework_SkippedTestError');
201   class_alias('\PHPUnit\Framework\TestCase', '\PHPUnit_Framework_TestCase');
202   class_alias('\PHPUnit\Util\Test', '\PHPUnit_Util_Test');
203   class_alias('\PHPUnit\Util\Xml', '\PHPUnit_Util_XML');
204 }