Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 23 additions & 64 deletions tests/phpunit/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,30 @@

/**
* @file
* Autoloader for Drupal PHPUnit testing.
* Autoloader for GovCMS PHPUnit testing.
*
* @see phpunit.xml.dist
* Based on Drupal core's tests/bootstrap.php, adapted for GovCMS test layout.
*
* @see phpunit.xml
*/

use Drupal\Component\Assertion\Handle;
use PHPUnit\Runner\Version;
declare(strict_types=1);

/**
* Finds all valid extension directories recursively within a given directory.
*
* @param string $scan_directory
* The directory that should be recursively scanned.
*
* @return array
* An associative array of extension directories found within the scanned
* directory, keyed by extension name.
*/
function drupal_phpunit_find_extension_directories($scan_directory)
{
function drupal_phpunit_find_extension_directories($scan_directory) {
$extensions = [];
$dirs = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($scan_directory, \RecursiveDirectoryIterator::FOLLOW_SYMLINKS));
foreach ($dirs as $dir) {
if (strpos($dir->getPathname(), '.info.yml') !== FALSE) {
if (str_contains($dir->getPathname(), '.info.yml')) {
// Cut off ".info.yml" from the filename for use as the extension name. We
// use getRealPath() so that we can scan extensions represented by
// directory aliases.
Expand All @@ -44,14 +45,14 @@ function drupal_phpunit_find_extension_directories($scan_directory)
* @return array
* An array of directories under which contributed extensions may exist.
*/
function drupal_phpunit_contrib_extension_directory_roots($root = NULL)
{
function drupal_phpunit_contrib_extension_directory_roots($root = NULL): array {
if ($root === NULL) {
$root = '/app/web';
}
$paths = [
$root . '/core/modules',
$root . '/core/profiles',
$root . '/core/themes',
$root . '/modules',
$root . '/profiles',
$root . '/themes',
Expand All @@ -68,7 +69,7 @@ function drupal_phpunit_contrib_extension_directory_roots($root = NULL)
$paths[] = is_dir("$path/profiles") ? realpath("$path/profiles") : NULL;
$paths[] = is_dir("$path/themes") ? realpath("$path/themes") : NULL;
}
return array_filter($paths, 'file_exists');
return array_filter($paths);
}

/**
Expand All @@ -80,38 +81,24 @@ function drupal_phpunit_contrib_extension_directory_roots($root = NULL)
* @return array
* An associative array of extension directories, keyed by their namespace.
*/
function drupal_phpunit_get_extension_namespaces($dirs)
{
$suite_names = ['Unit', 'Kernel', 'Functional', 'FunctionalJavascript'];
function drupal_phpunit_get_extension_namespaces($dirs) {
$namespaces = [];
foreach ($dirs as $extension => $dir) {
if (is_dir($dir . '/src')) {
// Register the PSR-4 directory for module-provided classes.
$namespaces['Drupal\\' . $extension . '\\'][] = $dir . '/src';
}
$test_dir = $dir . '/tests/src';
if (is_dir($test_dir)) {
foreach ($suite_names as $suite_name) {
$suite_dir = $test_dir . '/' . $suite_name;
if (is_dir($suite_dir)) {
// Register the PSR-4 directory for PHPUnit-based suites.
$namespaces['Drupal\\Tests\\' . $extension . '\\' . $suite_name . '\\'][] = $suite_dir;
}
}
// Extensions can have a \Drupal\extension\Traits namespace for
// cross-suite trait code.
$trait_dir = $test_dir . '/Traits';
if (is_dir($trait_dir)) {
$namespaces['Drupal\\Tests\\' . $extension . '\\Traits\\'][] = $trait_dir;
}
if (is_dir($dir . '/tests/src')) {
// Register the PSR-4 directory for PHPUnit-based suites.
$namespaces['Drupal\\Tests\\' . $extension . '\\'][] = $dir . '/tests/src';
}
}
return $namespaces;
}

// We define the COMPOSER_INSTALL constant, so that PHPUnit knows where to
// autoload from. This is needed for tests run in isolation mode, because
// phpunit.xml.dist is located in a non-default directory relative to the
// phpunit.xml is located in a non-default directory relative to the
// PHPUnit executable.
if (!defined('PHPUNIT_COMPOSER_INSTALL')) {
define('PHPUNIT_COMPOSER_INSTALL', '/app/web/autoload.php');
Expand All @@ -121,22 +108,23 @@ function drupal_phpunit_get_extension_namespaces($dirs)
* Populate class loader with additional namespaces for tests.
*
* We run this in a function to avoid setting the class loader to a global
* that can change. This change can cause unpredictable false positives for
* phpunit's global state change watcher. The class loader can be retrieved from
* that can change. This change can cause unpredictable false positives for the
* PHPUnit global state change watcher. The class loader can be retrieved from
* composer at any time by requiring autoload.php.
*/
function drupal_phpunit_populate_class_loader()
{
function drupal_phpunit_populate_class_loader() {

/** @var \Composer\Autoload\ClassLoader $loader */
$loader = require '/app/web/autoload.php';

// Start with classes in known locations.
$loader->add('Drupal\\BuildTests', '/app/web/core/tests');
$loader->add('Drupal\\Tests', '/app/web/core/tests');
$loader->add('Drupal\\TestSite', '/app/web/core/tests');
$loader->add('Drupal\\KernelTests', '/app/web/core/tests');
$loader->add('Drupal\\FunctionalTests', '/app/web/core/tests');
$loader->add('Drupal\\FunctionalJavascriptTests', '/app/web/core/tests');
$loader->add('Drupal\\TestTools', '/app/web/core/tests');

if (!isset($GLOBALS['namespaces'])) {
// Scan for arbitrary extension namespaces from core and contrib.
Expand All @@ -151,22 +139,15 @@ function drupal_phpunit_populate_class_loader()
}

return $loader;
};
}

// Do class loader population.
drupal_phpunit_populate_class_loader();

// Ensure we have the correct PHPUnit version for the version of PHP.
if (class_exists('\PHPUnit_Runner_Version')) {
$phpunit_version = \PHPUnit_Runner_Version::id();
} else {
$phpunit_version = Version::id();
}

// Set sane locale settings, to ensure consistent string, dates, times and
// numbers handling.
// @see \Drupal\Core\DrupalKernel::bootEnvironment()
setlocale(LC_ALL, 'C');
setlocale(LC_ALL, 'C.UTF-8', 'C');

// Set appropriate configuration for multi-byte strings.
mb_internal_encoding('utf-8');
Expand All @@ -178,25 +159,3 @@ function drupal_phpunit_populate_class_loader()
// and DST). This choice is made to prevent timezone related regressions and
// reduce the fragility of the testing system in general.
date_default_timezone_set('Australia/Sydney');

// Runtime assertions. PHPUnit follows the php.ini assert.active setting for
// runtime assertions. By default this setting is on. Ensure exceptions are
// thrown if an assert fails, but this call does not turn runtime assertions on
// if they weren't on already.
Handle::register();

// PHPUnit 4 to PHPUnit 6 bridge. Tests written for PHPUnit 4 need to work on
// PHPUnit 6 with a minimum of fuss.
if (version_compare($phpunit_version, '6.1', '>=')) {
class_alias('\PHPUnit\Framework\AssertionFailedError', '\PHPUnit_Framework_AssertionFailedError');
class_alias('\PHPUnit\Framework\Constraint\Count', '\PHPUnit_Framework_Constraint_Count');
class_alias('\PHPUnit\Framework\Error\Error', '\PHPUnit_Framework_Error');
class_alias('\PHPUnit\Framework\Error\Warning', '\PHPUnit_Framework_Error_Warning');
class_alias('\PHPUnit\Framework\ExpectationFailedException', '\PHPUnit_Framework_ExpectationFailedException');
class_alias('\PHPUnit\Framework\Exception', '\PHPUnit_Framework_Exception');
class_alias('\PHPUnit\Framework\MockObject\Matcher\InvokedRecorder', '\PHPUnit_Framework_MockObject_Matcher_InvokedRecorder');
class_alias('\PHPUnit\Framework\SkippedTestError', '\PHPUnit_Framework_SkippedTestError');
class_alias('\PHPUnit\Framework\TestCase', '\PHPUnit_Framework_TestCase');
class_alias('\PHPUnit\Util\Test', '\PHPUnit_Util_Test');
class_alias('\PHPUnit\Util\Xml', '\PHPUnit_Util_XML');
}