Skip to content

Commit

Permalink
Avoid namespace discovery for tests running in isolation.
Browse files Browse the repository at this point in the history
  • Loading branch information
sun committed Aug 1, 2014
1 parent 4a617b4 commit 1b9fa82
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 27 deletions.
27 changes: 20 additions & 7 deletions core/tests/Drupal/Tests/KernelTestBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,20 +83,32 @@ abstract class KernelTestBase extends \PHPUnit_Framework_TestCase implements Ser

/**
* {@inheritdoc}
*
* Fixes missing invocation of bootstrap.php when $preserveGlobalState is
* FALSE.
*
* @see https://github.com/sebastianbergmann/phpunit/pull/797
*/
protected function prepareTemplate(\Text_Template $template) {
$bootstrap_globals = '';
// Fix missing bootstrap.php when $preserveGlobalState is FALSE.
// @see https://github.com/sebastianbergmann/phpunit/pull/797
$bootstrap_globals .= '$__PHPUNIT_BOOTSTRAP = ' . var_export($GLOBALS['__PHPUNIT_BOOTSTRAP'], TRUE) . ";\n";
// @see /core/tests/bootstrap.php
$bootstrap_globals .= '$namespaces = ' . var_export($GLOBALS['namespaces'], TRUE) . ";\n";
$template->setVar(array(
'constants' => '',
'included_files' => '',
'globals' => '$GLOBALS[\'__PHPUNIT_BOOTSTRAP\'] = ' . var_export($GLOBALS['__PHPUNIT_BOOTSTRAP'], TRUE) . ";\n",
'globals' => $bootstrap_globals,
));
}

/**
* Returns whether the current test runs in isolation.
*
* @return bool
*
* @see https://github.com/sebastianbergmann/phpunit/pull/1350
*/
protected function isTestInIsolation() {
return function_exists('__phpunit_run_isolated_test');
}

protected $classLoader;
protected $siteDirectory;
protected $databasePrefix;
Expand Down Expand Up @@ -154,6 +166,7 @@ protected function setUp() {
require_once DRUPAL_ROOT . '/core/includes/bootstrap.inc';

// @todo Better way? PHPUnit seems to access it from constants.
// @see /core/tests/bootstrap.php
$this->classLoader = $GLOBALS['loader'];

// Set up virtual filesystem.
Expand Down Expand Up @@ -231,7 +244,7 @@ protected function setUp() {
// PHPUnit's @test annotations are intentionally ignored/not supported.
return strpos($method->getName(), 'test') === 0;
}));
if ($test_method_count > 1) {
if ($test_method_count > 1 && !$this->isTestInIsolation()) {
// Variant #1: Actually compiled + dumped Container class.
//$container = $this->getCompiledContainer($modules);
// Variant #2: Clone of a compiled, empty ContainerBuilder instance.
Expand Down
54 changes: 34 additions & 20 deletions core/tests/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ function drupal_phpunit_find_extension_directories($scan_directory) {
$extensions = array();
$dirs = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($scan_directory, \RecursiveDirectoryIterator::FOLLOW_SYMLINKS));
foreach ($dirs as $dir) {
if (strpos($dir->getPathname(), 'info.yml') !== FALSE) {
if (strpos($dir->getPathname(), '.info.yml') !== FALSE) {
// Cut off ".info.yml" from the filename for use as the extension name.
$extensions[substr($dir->getFilename(), 0, -9)] = $dir->getPathInfo()->getRealPath();
}
Expand All @@ -35,51 +35,65 @@ function drupal_phpunit_find_extension_directories($scan_directory) {
* An array of directories under which contributed extensions may exist.
*/
function drupal_phpunit_contrib_extension_directory_roots() {
$sites_path = __DIR__ . '/../../sites';
$paths = array();
// Note this also checks sites/../modules and sites/../profiles.
$root = dirname(dirname(__DIR__));
$paths = array(
$root . '/core/modules',
$root . '/core/profiles',
$root . '/modules',
$root . '/profiles',
);
$sites_path = $root . '/sites';
foreach (scandir($sites_path) as $site) {
if ($site[0] === '.' || $site === 'simpletest') {
continue;
}
$path = "$sites_path/$site";
$paths[] = is_dir("$path/modules") ? realpath("$path/modules") : NULL;
$paths[] = is_dir("$path/profiles") ? realpath("$path/profiles") : NULL;
if (is_dir("$path/modules")) {
$paths[] = "$path/modules";
}
if (is_dir("$path/profiles")) {
$paths[] = "$path/profiles";
}
}
return array_filter($paths);
return $paths;
}

/**
* Registers the namespace for each extension directory with the autoloader.
*
* @param Composer\Autoload\ClassLoader $loader
* The supplied autoloader.
* @param array $dirs
* An associative array of extension directories, keyed by extension name.
*/
function drupal_phpunit_register_extension_dirs(Composer\Autoload\ClassLoader $loader, $dirs) {
function drupal_phpunit_get_extension_namespaces($dirs) {
$namespaces = array();
foreach ($dirs as $extension => $dir) {
if (is_dir($dir . '/src')) {
// Register the PSR-4 directory for module-provided classes.
$loader->addPsr4('Drupal\\' . $extension . '\\', $dir . '/src');
$namespaces['Drupal\\' . $extension . '\\'][] = $dir . '/src';
}
if (is_dir($dir . '/tests/src')) {
// Register the PSR-4 directory for PHPUnit test classes.
$loader->addPsr4('Drupal\\' . $extension . '\Tests\\', $dir . '/tests/src');
$namespaces['Drupal\\' . $extension . '\Tests\\'][] = $dir . '/tests/src';
}
}
return $namespaces;
}

// Start with classes in known locations.
$loader = require __DIR__ . '/../vendor/autoload.php';
$loader->add('Drupal\\Tests', __DIR__);

// Scan for arbitrary extension namespaces from core and contrib.
$extension_roots = array_merge(array(
__DIR__ . '/../modules',
__DIR__ . '/../profiles',
), drupal_phpunit_contrib_extension_directory_roots());
if (!isset($GLOBALS['namespaces'])) {
// Scan for arbitrary extension namespaces from core and contrib.
$extension_roots = drupal_phpunit_contrib_extension_directory_roots();

$dirs = array_map('drupal_phpunit_find_extension_directories', $extension_roots);
$dirs = array_reduce($dirs, 'array_merge', array());
drupal_phpunit_register_extension_dirs($loader, $dirs);
$dirs = array_map('drupal_phpunit_find_extension_directories', $extension_roots);
$dirs = array_reduce($dirs, 'array_merge', array());
$GLOBALS['namespaces'] = drupal_phpunit_get_extension_namespaces($dirs);
}
foreach ($GLOBALS['namespaces'] as $prefix => $paths) {
$loader->addPsr4($prefix, $paths);
}

// Look into removing these later.
// PHPUnit process isolation template re-defines constants and reloads included
Expand Down

0 comments on commit 1b9fa82

Please sign in to comment.