function TestDiscovery::scanDirectory

Same name in other branches
  1. 9 core/lib/Drupal/Core/Test/TestDiscovery.php \Drupal\Core\Test\TestDiscovery::scanDirectory()
  2. 8.9.x core/lib/Drupal/Core/Test/TestDiscovery.php \Drupal\Core\Test\TestDiscovery::scanDirectory()
  3. 11.x 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 256

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;
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.