Same name and namespace in other branches
  1. 8.9.x core/lib/Drupal/Core/Test/TestDiscovery.php \Drupal\Core\Test\TestDiscovery::scanDirectory()
  2. 9 core/lib/Drupal/Core/Test/TestDiscovery.php \Drupal\Core\Test\TestDiscovery::scanDirectory()

Scans a given directory for class files.

@todo Limit to '*Test.php' files (~10% less files to reflect/introspect).

Parameters

string $namespace_prefix: The namespace prefix to use for discovered classes. Must contain a trailing namespace separator (backslash). For example: 'Drupal\\node\\Tests\\'

string $path: The directory path to scan. For example: '/path/to/drupal/core/modules/node/tests/src'

Return value

array An associative array whose keys are fully-qualified class names and whose values are corresponding filesystem path names.

Throws

\InvalidArgumentException If $namespace_prefix does not end in a namespace separator (backslash).

See also

https://www.drupal.org/node/2296635

3 calls to TestDiscovery::scanDirectory()
TestDiscovery::findAllClassFiles in core/lib/Drupal/Core/Test/TestDiscovery.php
Discovers all class files in all available extensions.
TestDiscoveryTest::testScanDirectoryNoAbstract in core/tests/Drupal/Tests/Core/Test/TestDiscoveryTest.php
Ensure TestDiscovery::scanDirectory() ignores certain abstract file types.
TestSuiteBase::addTestsBySuiteNamespace in core/tests/TestSuites/TestSuiteBase.php
Find and add tests to the suite for core and any extensions.

File

core/lib/Drupal/Core/Test/TestDiscovery.php, line 250

Class

TestDiscovery
Discovers available tests.

Namespace

Drupal\Core\Test

Code

public static function scanDirectory($namespace_prefix, $path) {
  if (!str_ends_with($namespace_prefix, '\\')) {
    throw new \InvalidArgumentException("Namespace prefix for {$path} must contain a trailing namespace separator.");
  }
  $flags = \FilesystemIterator::UNIX_PATHS;
  $flags |= \FilesystemIterator::SKIP_DOTS;
  $flags |= \FilesystemIterator::FOLLOW_SYMLINKS;
  $flags |= \FilesystemIterator::CURRENT_AS_SELF;
  $flags |= \FilesystemIterator::KEY_AS_FILENAME;
  $iterator = new \RecursiveDirectoryIterator($path, $flags);
  $filter = new \RecursiveCallbackFilterIterator($iterator, function ($current, $file_name, $iterator) {
    if ($iterator
      ->hasChildren()) {
      return TRUE;
    }

    // We don't want to discover abstract TestBase classes, traits or
    // interfaces. They can be deprecated and will call @trigger_error()
    // during discovery.
    return str_ends_with($file_name, '.php') && !str_ends_with($file_name, 'TestBase.php') && !str_ends_with($file_name, 'Trait.php') && !str_ends_with($file_name, 'Interface.php');
  });
  $files = new \RecursiveIteratorIterator($filter);
  $classes = [];
  foreach ($files as $fileinfo) {
    $class = $namespace_prefix;
    if ('' !== ($subpath = $fileinfo
      ->getSubPath())) {
      $class .= strtr($subpath, '/', '\\') . '\\';
    }
    $class .= $fileinfo
      ->getBasename('.php');
    $classes[$class] = $fileinfo
      ->getPathname();
  }
  return $classes;
}