Skip to main content
Drupal API
User account menu
  • Log in

Breadcrumb

  1. Drupal Core 11.1.x
  2. NamePrettifier.php

class NamePrettifier

@no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit

@internal This class is not covered by the backward compatibility promise for PHPUnit

Hierarchy

  • class \PHPUnit\Logging\TestDox\NamePrettifier

Expanded class hierarchy of NamePrettifier

1 file declares its use of NamePrettifier
TestDoxBuilder.php in vendor/phpunit/phpunit/src/Event/Value/Test/TestDoxBuilder.php

File

vendor/phpunit/phpunit/src/Logging/TestDox/NamePrettifier.php, line 55

Namespace

PHPUnit\Logging\TestDox
View source
final class NamePrettifier {
    
    /**
     * @psalm-var array<string, int>
     */
    private static array $strings = [];
    
    /**
     * @psalm-param class-string $className
     */
    public function prettifyTestClassName(string $className) : string {
        if (class_exists($className)) {
            $classLevelTestDox = MetadataRegistry::parser()->forClass($className)
                ->isTestDox();
            if ($classLevelTestDox->isNotEmpty()) {
                $classLevelTestDox = $classLevelTestDox->asArray()[0];
                assert($classLevelTestDox instanceof TestDox);
                return $classLevelTestDox->text();
            }
        }
        $parts = explode('\\', $className);
        $className = array_pop($parts);
        if (str_ends_with($className, 'Test')) {
            $className = substr($className, 0, strlen($className) - strlen('Test'));
        }
        if (str_starts_with($className, 'Tests')) {
            $className = substr($className, strlen('Tests'));
        }
        elseif (str_starts_with($className, 'Test')) {
            $className = substr($className, strlen('Test'));
        }
        if (empty($className)) {
            $className = 'UnnamedTests';
        }
        if (!empty($parts)) {
            $parts[] = $className;
            $fullyQualifiedName = implode('\\', $parts);
        }
        else {
            $fullyQualifiedName = $className;
        }
        $result = preg_replace('/(?<=[[:lower:]])(?=[[:upper:]])/u', ' ', $className);
        if ($fullyQualifiedName !== $className) {
            return $result . ' (' . $fullyQualifiedName . ')';
        }
        return $result;
    }
    // NOTE: this method is on a hot path and very performance sensitive. change with care.
    public function prettifyTestMethodName(string $name) : string {
        if ($name === '') {
            return '';
        }
        $string = rtrim($name, '0123456789');
        if (array_key_exists($string, self::$strings)) {
            $name = $string;
        }
        elseif ($string === $name) {
            self::$strings[$string] = 1;
        }
        if (str_starts_with($name, 'test_')) {
            $name = substr($name, 5);
        }
        elseif (str_starts_with($name, 'test')) {
            $name = substr($name, 4);
        }
        if ($name === '') {
            return '';
        }
        $name[0] = strtoupper($name[0]);
        $noUnderscore = str_replace('_', ' ', $name);
        if ($noUnderscore !== $name) {
            return trim($noUnderscore);
        }
        $wasNumeric = false;
        $buffer = '';
        $len = strlen($name);
        for ($i = 0; $i < $len; $i++) {
            if ($i > 0 && $name[$i] >= 'A' && $name[$i] <= 'Z') {
                $buffer .= ' ' . strtolower($name[$i]);
            }
            else {
                $isNumeric = $name[$i] >= '0' && $name[$i] <= '9';
                if (!$wasNumeric && $isNumeric) {
                    $buffer .= ' ';
                    $wasNumeric = true;
                }
                if ($wasNumeric && !$isNumeric) {
                    $wasNumeric = false;
                }
                $buffer .= $name[$i];
            }
        }
        return $buffer;
    }
    public function prettifyTestCase(TestCase $test, bool $colorize) : string {
        $annotationWithPlaceholders = false;
        $methodLevelTestDox = MetadataRegistry::parser()->forMethod($test::class, $test->name())
            ->isTestDox()
            ->isMethodLevel();
        if ($methodLevelTestDox->isNotEmpty()) {
            $methodLevelTestDox = $methodLevelTestDox->asArray()[0];
            assert($methodLevelTestDox instanceof TestDox);
            $result = $methodLevelTestDox->text();
            if (str_contains($result, '$')) {
                $annotation = $result;
                $providedData = $this->mapTestMethodParameterNamesToProvidedDataValues($test, $colorize);
                $variables = array_map(static fn(string $variable): string => sprintf('/%s(?=\\b)/', preg_quote($variable, '/')), array_keys($providedData));
                $result = preg_replace($variables, $providedData, $annotation);
                $annotationWithPlaceholders = true;
            }
        }
        else {
            $result = $this->prettifyTestMethodName($test->name());
        }
        if (!$annotationWithPlaceholders && $test->usesDataProvider()) {
            $result .= $this->prettifyDataSet($test, $colorize);
        }
        return $result;
    }
    public function prettifyDataSet(TestCase $test, bool $colorize) : string {
        if (!$colorize) {
            return $test->dataSetAsString();
        }
        if (is_int($test->dataName())) {
            return Color::dim(' with data set ') . Color::colorize('fg-cyan', (string) $test->dataName());
        }
        return Color::dim(' with ') . Color::colorize('fg-cyan', Color::visualizeWhitespace($test->dataName()));
    }
    private function mapTestMethodParameterNamesToProvidedDataValues(TestCase $test, bool $colorize) : array {
        assert(method_exists($test, $test->name()));
        
        /** @noinspection PhpUnhandledExceptionInspection */
        $reflector = new ReflectionMethod($test::class, $test->name());
        $providedData = [];
        $providedDataValues = array_values($test->providedData());
        $i = 0;
        $providedData['$_dataName'] = $test->dataName();
        foreach ($reflector->getParameters() as $parameter) {
            if (!array_key_exists($i, $providedDataValues) && $parameter->isDefaultValueAvailable()) {
                $providedDataValues[$i] = $parameter->getDefaultValue();
            }
            $value = $providedDataValues[$i++] ?? null;
            if (is_object($value)) {
                $reflector = new ReflectionObject($value);
                if ($reflector->isEnum()) {
                    $enumReflector = new ReflectionEnum($value);
                    if ($enumReflector->isBacked()) {
                        $value = $value->value;
                    }
                    else {
                        $value = $value->name;
                    }
                }
                elseif ($reflector->hasMethod('__toString')) {
                    $value = (string) $value;
                }
                else {
                    $value = $value::class;
                }
            }
            if (!is_scalar($value)) {
                $value = gettype($value);
                if ($value === 'NULL') {
                    $value = 'null';
                }
            }
            if (is_bool($value) || is_int($value) || is_float($value)) {
                $value = (new Exporter())->export($value);
            }
            if ($value === '') {
                if ($colorize) {
                    $value = Color::colorize('dim,underlined', 'empty');
                }
                else {
                    $value = "''";
                }
            }
            $providedData['$' . $parameter->getName()] = str_replace('$', '\\$', $value);
        }
        if ($colorize) {
            $providedData = array_map(static fn($value) => Color::colorize('fg-cyan', Color::visualizeWhitespace((string) $value, true)), $providedData);
        }
        return $providedData;
    }

}

Members

Title Sort descending Modifiers Object type Summary
NamePrettifier::$strings private static property @psalm-var array&lt;string, int&gt;
NamePrettifier::mapTestMethodParameterNamesToProvidedDataValues private function
NamePrettifier::prettifyDataSet public function
NamePrettifier::prettifyTestCase public function
NamePrettifier::prettifyTestClassName public function @psalm-param class-string $className
NamePrettifier::prettifyTestMethodName public function
RSS feed
Powered by Drupal