One Hat Cyber Team
Your IP:
216.73.216.176
Server IP:
198.54.114.155
Server:
Linux server71.web-hosting.com 4.18.0-513.18.1.lve.el8.x86_64 #1 SMP Thu Feb 22 12:55:50 UTC 2024 x86_64
Server Software:
LiteSpeed
PHP Version:
5.6.40
Create File
|
Create Folder
Execute
Dir :
~
/
proc
/
self
/
cwd
/
View File Name :
Metadata.tar
DependsOnMethod.php 0000644 00000003423 15111216103 0010266 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class DependsOnMethod extends Metadata { /** * @psalm-var class-string */ private readonly string $className; /** * @psalm-var non-empty-string */ private readonly string $methodName; private readonly bool $deepClone; private readonly bool $shallowClone; /** * @psalm-param 0|1 $level * @psalm-param class-string $className * @psalm-param non-empty-string $methodName */ protected function __construct(int $level, string $className, string $methodName, bool $deepClone, bool $shallowClone) { parent::__construct($level); $this->className = $className; $this->methodName = $methodName; $this->deepClone = $deepClone; $this->shallowClone = $shallowClone; } /** * @psalm-assert-if-true DependsOnMethod $this */ public function isDependsOnMethod(): bool { return true; } /** * @psalm-return class-string */ public function className(): string { return $this->className; } /** * @psalm-return non-empty-string */ public function methodName(): string { return $this->methodName; } public function deepClone(): bool { return $this->deepClone; } public function shallowClone(): bool { return $this->shallowClone; } } RequiresMethod.php 0000644 00000002623 15111216103 0010207 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class RequiresMethod extends Metadata { /** * @psalm-var class-string */ private readonly string $className; /** * @psalm-var non-empty-string */ private readonly string $methodName; /** * @psalm-param 0|1 $level * @psalm-param class-string $className * @psalm-param non-empty-string $methodName */ protected function __construct(int $level, string $className, string $methodName) { parent::__construct($level); $this->className = $className; $this->methodName = $methodName; } /** * @psalm-assert-if-true RequiresMethod $this */ public function isRequiresMethod(): bool { return true; } /** * @psalm-return class-string */ public function className(): string { return $this->className; } /** * @psalm-return non-empty-string */ public function methodName(): string { return $this->methodName; } } IgnoreFunctionForCodeCoverage.php 0000644 00000002322 15111216103 0013112 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5513 */ final class IgnoreFunctionForCodeCoverage extends Metadata { /** * @psalm-var non-empty-string */ private readonly string $functionName; /** * @psalm-param 0|1 $level * @psalm-param non-empty-string $functionName */ protected function __construct(int $level, string $functionName) { parent::__construct($level); $this->functionName = $functionName; } /** * @psalm-assert-if-true IgnoreFunctionForCodeCoverage $this */ public function isIgnoreFunctionForCodeCoverage(): bool { return true; } /** * @psalm-return non-empty-string */ public function functionName(): string { return $this->functionName; } } BackupGlobals.php 0000644 00000001627 15111216104 0007764 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class BackupGlobals extends Metadata { private readonly bool $enabled; /** * @psalm-param 0|1 $level */ protected function __construct(int $level, bool $enabled) { parent::__construct($level); $this->enabled = $enabled; } /** * @psalm-assert-if-true BackupGlobals $this */ public function isBackupGlobals(): bool { return true; } public function enabled(): bool { return $this->enabled; } } PreCondition.php 0000644 00000001134 15111216104 0007641 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class PreCondition extends Metadata { /** * @psalm-assert-if-true PreCondition $this */ public function isPreCondition(): bool { return true; } } MetadataCollectionIterator.php 0000644 00000002301 15111216104 0012507 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; use function count; use Iterator; /** * @template-implements Iterator<int, Metadata> * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class MetadataCollectionIterator implements Iterator { /** * @psalm-var list<Metadata> */ private readonly array $metadata; private int $position = 0; public function __construct(MetadataCollection $metadata) { $this->metadata = $metadata->asArray(); } public function rewind(): void { $this->position = 0; } public function valid(): bool { return $this->position < count($this->metadata); } public function key(): int { return $this->position; } public function current(): Metadata { return $this->metadata[$this->position]; } public function next(): void { $this->position++; } } IgnoreMethodForCodeCoverage.php 0000644 00000003005 15111216104 0012545 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5513 */ final class IgnoreMethodForCodeCoverage extends Metadata { /** * @psalm-var class-string */ private readonly string $className; /** * @psalm-var non-empty-string */ private readonly string $methodName; /** * @psalm-param 0|1 $level * @psalm-param class-string $className * @psalm-param non-empty-string $methodName */ protected function __construct(int $level, string $className, string $methodName) { parent::__construct($level); $this->className = $className; $this->methodName = $methodName; } /** * @psalm-assert-if-true IgnoreMethodForCodeCoverage $this */ public function isIgnoreMethodForCodeCoverage(): bool { return true; } /** * @psalm-return class-string */ public function className(): string { return $this->className; } /** * @psalm-return non-empty-string */ public function methodName(): string { return $this->methodName; } } MetadataCollection.php 0000644 00000033375 15111216105 0011015 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; use function array_filter; use function array_merge; use function count; use Countable; use IteratorAggregate; /** * @template-implements IteratorAggregate<int, Metadata> * * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class MetadataCollection implements Countable, IteratorAggregate { /** * @psalm-var list<Metadata> */ private readonly array $metadata; /** * @psalm-param list<Metadata> $metadata */ public static function fromArray(array $metadata): self { return new self(...$metadata); } private function __construct(Metadata ...$metadata) { $this->metadata = $metadata; } /** * @psalm-return list<Metadata> */ public function asArray(): array { return $this->metadata; } public function count(): int { return count($this->metadata); } public function isEmpty(): bool { return $this->count() === 0; } public function isNotEmpty(): bool { return $this->count() > 0; } public function getIterator(): MetadataCollectionIterator { return new MetadataCollectionIterator($this); } public function mergeWith(self $other): self { return new self( ...array_merge( $this->asArray(), $other->asArray(), ), ); } public function isClassLevel(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isClassLevel(), ), ); } public function isMethodLevel(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isMethodLevel(), ), ); } public function isAfter(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isAfter(), ), ); } public function isAfterClass(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isAfterClass(), ), ); } public function isBackupGlobals(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isBackupGlobals(), ), ); } public function isBackupStaticProperties(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isBackupStaticProperties(), ), ); } public function isBeforeClass(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isBeforeClass(), ), ); } public function isBefore(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isBefore(), ), ); } public function isCovers(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isCovers(), ), ); } public function isCoversClass(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isCoversClass(), ), ); } public function isCoversDefaultClass(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isCoversDefaultClass(), ), ); } public function isCoversFunction(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isCoversFunction(), ), ); } public function isExcludeGlobalVariableFromBackup(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isExcludeGlobalVariableFromBackup(), ), ); } public function isExcludeStaticPropertyFromBackup(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isExcludeStaticPropertyFromBackup(), ), ); } public function isCoversNothing(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isCoversNothing(), ), ); } public function isDataProvider(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isDataProvider(), ), ); } public function isDepends(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isDependsOnClass() || $metadata->isDependsOnMethod(), ), ); } public function isDependsOnClass(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isDependsOnClass(), ), ); } public function isDependsOnMethod(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isDependsOnMethod(), ), ); } public function isDoesNotPerformAssertions(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isDoesNotPerformAssertions(), ), ); } public function isGroup(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isGroup(), ), ); } /** * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5513 */ public function isIgnoreClassForCodeCoverage(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isIgnoreClassForCodeCoverage(), ), ); } /** * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5513 */ public function isIgnoreMethodForCodeCoverage(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isIgnoreMethodForCodeCoverage(), ), ); } /** * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5513 */ public function isIgnoreFunctionForCodeCoverage(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isIgnoreFunctionForCodeCoverage(), ), ); } public function isRunClassInSeparateProcess(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isRunClassInSeparateProcess(), ), ); } public function isRunInSeparateProcess(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isRunInSeparateProcess(), ), ); } public function isRunTestsInSeparateProcesses(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isRunTestsInSeparateProcesses(), ), ); } public function isTest(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isTest(), ), ); } public function isPreCondition(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isPreCondition(), ), ); } public function isPostCondition(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isPostCondition(), ), ); } public function isPreserveGlobalState(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isPreserveGlobalState(), ), ); } public function isRequiresMethod(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isRequiresMethod(), ), ); } public function isRequiresFunction(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isRequiresFunction(), ), ); } public function isRequiresOperatingSystem(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isRequiresOperatingSystem(), ), ); } public function isRequiresOperatingSystemFamily(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isRequiresOperatingSystemFamily(), ), ); } public function isRequiresPhp(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isRequiresPhp(), ), ); } public function isRequiresPhpExtension(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isRequiresPhpExtension(), ), ); } public function isRequiresPhpunit(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isRequiresPhpunit(), ), ); } public function isRequiresSetting(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isRequiresSetting(), ), ); } public function isTestDox(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isTestDox(), ), ); } public function isTestWith(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isTestWith(), ), ); } public function isUses(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isUses(), ), ); } public function isUsesClass(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isUsesClass(), ), ); } public function isUsesDefaultClass(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isUsesDefaultClass(), ), ); } public function isUsesFunction(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isUsesFunction(), ), ); } public function isWithoutErrorHandler(): self { return new self( ...array_filter( $this->metadata, static fn (Metadata $metadata): bool => $metadata->isWithoutErrorHandler(), ), ); } } Api/HookMethods.php 0000644 00000007245 15111216105 0010213 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata\Api; use function array_unshift; use function assert; use function class_exists; use PHPUnit\Metadata\Parser\Registry; use PHPUnit\Util\Reflection; use ReflectionClass; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class HookMethods { /** * @psalm-var array<class-string, array{beforeClass: list<non-empty-string>, before: list<non-empty-string>, preCondition: list<non-empty-string>, postCondition: list<non-empty-string>, after: list<non-empty-string>, afterClass: list<non-empty-string>}> */ private static array $hookMethods = []; /** * @psalm-param class-string $className * * @psalm-return array{beforeClass: list<non-empty-string>, before: list<non-empty-string>, preCondition: list<non-empty-string>, postCondition: list<non-empty-string>, after: list<non-empty-string>, afterClass: list<non-empty-string>} */ public function hookMethods(string $className): array { if (!class_exists($className)) { return self::emptyHookMethodsArray(); } if (isset(self::$hookMethods[$className])) { return self::$hookMethods[$className]; } self::$hookMethods[$className] = self::emptyHookMethodsArray(); foreach (Reflection::methodsInTestClass(new ReflectionClass($className)) as $method) { $methodName = $method->getName(); assert(!empty($methodName)); $metadata = Registry::parser()->forMethod($className, $methodName); if ($method->isStatic()) { if ($metadata->isBeforeClass()->isNotEmpty()) { array_unshift( self::$hookMethods[$className]['beforeClass'], $methodName, ); } if ($metadata->isAfterClass()->isNotEmpty()) { self::$hookMethods[$className]['afterClass'][] = $methodName; } } if ($metadata->isBefore()->isNotEmpty()) { array_unshift( self::$hookMethods[$className]['before'], $methodName, ); } if ($metadata->isPreCondition()->isNotEmpty()) { array_unshift( self::$hookMethods[$className]['preCondition'], $methodName, ); } if ($metadata->isPostCondition()->isNotEmpty()) { self::$hookMethods[$className]['postCondition'][] = $methodName; } if ($metadata->isAfter()->isNotEmpty()) { self::$hookMethods[$className]['after'][] = $methodName; } } return self::$hookMethods[$className]; } /** * @psalm-return array{beforeClass: list<non-empty-string>, before: list<non-empty-string>, preCondition: list<non-empty-string>, postCondition: list<non-empty-string>, after: list<non-empty-string>, afterClass: list<non-empty-string>} */ private function emptyHookMethodsArray(): array { return [ 'beforeClass' => ['setUpBeforeClass'], 'before' => ['setUp'], 'preCondition' => ['assertPreConditions'], 'postCondition' => ['assertPostConditions'], 'after' => ['tearDown'], 'afterClass' => ['tearDownAfterClass'], ]; } } Api/CodeCoverage.php 0000644 00000025015 15111216105 0010310 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata\Api; use function array_unique; use function array_values; use function assert; use function count; use function interface_exists; use function sprintf; use function str_starts_with; use PHPUnit\Framework\CodeCoverageException; use PHPUnit\Framework\InvalidCoversTargetException; use PHPUnit\Framework\TestSuite; use PHPUnit\Metadata\Covers; use PHPUnit\Metadata\CoversClass; use PHPUnit\Metadata\CoversDefaultClass; use PHPUnit\Metadata\CoversFunction; use PHPUnit\Metadata\IgnoreClassForCodeCoverage; use PHPUnit\Metadata\IgnoreFunctionForCodeCoverage; use PHPUnit\Metadata\IgnoreMethodForCodeCoverage; use PHPUnit\Metadata\Parser\Registry; use PHPUnit\Metadata\Uses; use PHPUnit\Metadata\UsesClass; use PHPUnit\Metadata\UsesDefaultClass; use PHPUnit\Metadata\UsesFunction; use RecursiveIteratorIterator; use SebastianBergmann\CodeUnit\CodeUnitCollection; use SebastianBergmann\CodeUnit\InvalidCodeUnitException; use SebastianBergmann\CodeUnit\Mapper; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class CodeCoverage { /** * @psalm-param class-string $className * @psalm-param non-empty-string $methodName * * @psalm-return array<string,list<int>>|false * * @throws CodeCoverageException */ public function linesToBeCovered(string $className, string $methodName): array|false { if (!$this->shouldCodeCoverageBeCollectedFor($className, $methodName)) { return false; } $metadataForClass = Registry::parser()->forClass($className); $classShortcut = null; if ($metadataForClass->isCoversDefaultClass()->isNotEmpty()) { if (count($metadataForClass->isCoversDefaultClass()) > 1) { throw new CodeCoverageException( sprintf( 'More than one @coversDefaultClass annotation for class or interface "%s"', $className, ), ); } $metadata = $metadataForClass->isCoversDefaultClass()->asArray()[0]; assert($metadata instanceof CoversDefaultClass); $classShortcut = $metadata->className(); } $codeUnits = CodeUnitCollection::fromList(); $mapper = new Mapper; foreach (Registry::parser()->forClassAndMethod($className, $methodName) as $metadata) { if ($metadata->isCoversClass() || $metadata->isCoversFunction()) { assert($metadata instanceof CoversClass || $metadata instanceof CoversFunction); try { $codeUnits = $codeUnits->mergeWith( $mapper->stringToCodeUnits($metadata->asStringForCodeUnitMapper()), ); } catch (InvalidCodeUnitException $e) { if ($metadata->isCoversClass()) { $type = 'Class'; } else { $type = 'Function'; } throw new InvalidCoversTargetException( sprintf( '%s "%s" is not a valid target for code coverage', $type, $metadata->asStringForCodeUnitMapper(), ), $e->getCode(), $e, ); } } elseif ($metadata->isCovers()) { assert($metadata instanceof Covers); $target = $metadata->target(); if (interface_exists($target)) { throw new InvalidCoversTargetException( sprintf( 'Trying to @cover interface "%s".', $target, ), ); } if ($classShortcut !== null && str_starts_with($target, '::')) { $target = $classShortcut . $target; } try { $codeUnits = $codeUnits->mergeWith($mapper->stringToCodeUnits($target)); } catch (InvalidCodeUnitException $e) { throw new InvalidCoversTargetException( sprintf( '"@covers %s" is invalid', $target, ), $e->getCode(), $e, ); } } } return $mapper->codeUnitsToSourceLines($codeUnits); } /** * @psalm-param class-string $className * @psalm-param non-empty-string $methodName * * @psalm-return array<string,list<int>> * * @throws CodeCoverageException */ public function linesToBeUsed(string $className, string $methodName): array { $metadataForClass = Registry::parser()->forClass($className); $classShortcut = null; if ($metadataForClass->isUsesDefaultClass()->isNotEmpty()) { if (count($metadataForClass->isUsesDefaultClass()) > 1) { throw new CodeCoverageException( sprintf( 'More than one @usesDefaultClass annotation for class or interface "%s"', $className, ), ); } $metadata = $metadataForClass->isUsesDefaultClass()->asArray()[0]; assert($metadata instanceof UsesDefaultClass); $classShortcut = $metadata->className(); } $codeUnits = CodeUnitCollection::fromList(); $mapper = new Mapper; foreach (Registry::parser()->forClassAndMethod($className, $methodName) as $metadata) { if ($metadata->isUsesClass() || $metadata->isUsesFunction()) { assert($metadata instanceof UsesClass || $metadata instanceof UsesFunction); try { $codeUnits = $codeUnits->mergeWith( $mapper->stringToCodeUnits($metadata->asStringForCodeUnitMapper()), ); } catch (InvalidCodeUnitException $e) { if ($metadata->isUsesClass()) { $type = 'Class'; } else { $type = 'Function'; } throw new InvalidCoversTargetException( sprintf( '%s "%s" is not a valid target for code coverage', $type, $metadata->asStringForCodeUnitMapper(), ), $e->getCode(), $e, ); } } elseif ($metadata->isUses()) { assert($metadata instanceof Uses); $target = $metadata->target(); if ($classShortcut !== null && str_starts_with($target, '::')) { $target = $classShortcut . $target; } try { $codeUnits = $codeUnits->mergeWith($mapper->stringToCodeUnits($target)); } catch (InvalidCodeUnitException $e) { throw new InvalidCoversTargetException( sprintf( '"@uses %s" is invalid', $target, ), $e->getCode(), $e, ); } } } return $mapper->codeUnitsToSourceLines($codeUnits); } /** * @psalm-return array<string,list<int>> */ public function linesToBeIgnored(TestSuite $testSuite): array { $codeUnits = CodeUnitCollection::fromList(); $mapper = new Mapper; foreach ($this->testCaseClassesIn($testSuite) as $testCaseClassName) { $codeUnits = $codeUnits->mergeWith( $this->codeUnitsIgnoredBy($testCaseClassName), ); } return $mapper->codeUnitsToSourceLines($codeUnits); } /** * @psalm-param class-string $className * @psalm-param non-empty-string $methodName */ public function shouldCodeCoverageBeCollectedFor(string $className, string $methodName): bool { $metadataForClass = Registry::parser()->forClass($className); $metadataForMethod = Registry::parser()->forMethod($className, $methodName); if ($metadataForMethod->isCoversNothing()->isNotEmpty()) { return false; } if ($metadataForMethod->isCovers()->isNotEmpty() || $metadataForMethod->isCoversClass()->isNotEmpty() || $metadataForMethod->isCoversFunction()->isNotEmpty()) { return true; } if ($metadataForClass->isCoversNothing()->isNotEmpty()) { return false; } return true; } /** * @psalm-return list<class-string> */ private function testCaseClassesIn(TestSuite $testSuite): array { $classNames = []; foreach (new RecursiveIteratorIterator($testSuite) as $test) { $classNames[] = $test::class; } return array_values(array_unique($classNames)); } /** * @psalm-param class-string $className */ private function codeUnitsIgnoredBy(string $className): CodeUnitCollection { $codeUnits = CodeUnitCollection::fromList(); $mapper = new Mapper; foreach (Registry::parser()->forClass($className) as $metadata) { if ($metadata instanceof IgnoreClassForCodeCoverage) { $codeUnits = $codeUnits->mergeWith( $mapper->stringToCodeUnits($metadata->className()), ); } if ($metadata instanceof IgnoreMethodForCodeCoverage) { $codeUnits = $codeUnits->mergeWith( $mapper->stringToCodeUnits($metadata->className() . '::' . $metadata->methodName()), ); } if ($metadata instanceof IgnoreFunctionForCodeCoverage) { $codeUnits = $codeUnits->mergeWith( $mapper->stringToCodeUnits('::' . $metadata->functionName()), ); } } return $codeUnits; } } Api/Requirements.php 0000644 00000012313 15111216105 0010442 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata\Api; use const PHP_OS; use const PHP_OS_FAMILY; use const PHP_VERSION; use function addcslashes; use function assert; use function extension_loaded; use function function_exists; use function ini_get; use function method_exists; use function phpversion; use function preg_match; use function sprintf; use PHPUnit\Metadata\Parser\Registry; use PHPUnit\Metadata\RequiresFunction; use PHPUnit\Metadata\RequiresMethod; use PHPUnit\Metadata\RequiresOperatingSystem; use PHPUnit\Metadata\RequiresOperatingSystemFamily; use PHPUnit\Metadata\RequiresPhp; use PHPUnit\Metadata\RequiresPhpExtension; use PHPUnit\Metadata\RequiresPhpunit; use PHPUnit\Metadata\RequiresSetting; use PHPUnit\Runner\Version; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class Requirements { /** * @psalm-param class-string $className * @psalm-param non-empty-string $methodName * * @psalm-return list<string> */ public function requirementsNotSatisfiedFor(string $className, string $methodName): array { $notSatisfied = []; foreach (Registry::parser()->forClassAndMethod($className, $methodName) as $metadata) { if ($metadata->isRequiresPhp()) { assert($metadata instanceof RequiresPhp); if (!$metadata->versionRequirement()->isSatisfiedBy(PHP_VERSION)) { $notSatisfied[] = sprintf( 'PHP %s is required.', $metadata->versionRequirement()->asString(), ); } } if ($metadata->isRequiresPhpExtension()) { assert($metadata instanceof RequiresPhpExtension); if (!extension_loaded($metadata->extension()) || ($metadata->hasVersionRequirement() && !$metadata->versionRequirement()->isSatisfiedBy(phpversion($metadata->extension())))) { $notSatisfied[] = sprintf( 'PHP extension %s%s is required.', $metadata->extension(), $metadata->hasVersionRequirement() ? (' ' . $metadata->versionRequirement()->asString()) : '', ); } } if ($metadata->isRequiresPhpunit()) { assert($metadata instanceof RequiresPhpunit); if (!$metadata->versionRequirement()->isSatisfiedBy(Version::id())) { $notSatisfied[] = sprintf( 'PHPUnit %s is required.', $metadata->versionRequirement()->asString(), ); } } if ($metadata->isRequiresOperatingSystemFamily()) { assert($metadata instanceof RequiresOperatingSystemFamily); if ($metadata->operatingSystemFamily() !== PHP_OS_FAMILY) { $notSatisfied[] = sprintf( 'Operating system %s is required.', $metadata->operatingSystemFamily(), ); } } if ($metadata->isRequiresOperatingSystem()) { assert($metadata instanceof RequiresOperatingSystem); $pattern = sprintf( '/%s/i', addcslashes($metadata->operatingSystem(), '/'), ); if (!preg_match($pattern, PHP_OS)) { $notSatisfied[] = sprintf( 'Operating system %s is required.', $metadata->operatingSystem(), ); } } if ($metadata->isRequiresFunction()) { assert($metadata instanceof RequiresFunction); if (!function_exists($metadata->functionName())) { $notSatisfied[] = sprintf( 'Function %s() is required.', $metadata->functionName(), ); } } if ($metadata->isRequiresMethod()) { assert($metadata instanceof RequiresMethod); if (!method_exists($metadata->className(), $metadata->methodName())) { $notSatisfied[] = sprintf( 'Method %s::%s() is required.', $metadata->className(), $metadata->methodName(), ); } } if ($metadata->isRequiresSetting()) { assert($metadata instanceof RequiresSetting); if (ini_get($metadata->setting()) !== $metadata->value()) { $notSatisfied[] = sprintf( 'Setting "%s" is required to be "%s".', $metadata->setting(), $metadata->value(), ); } } } return $notSatisfied; } } Api/DataProvider.php 0000644 00000024003 15111216105 0010342 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata\Api; use function array_key_exists; use function array_merge; use function assert; use function explode; use function is_array; use function is_int; use function json_decode; use function json_last_error; use function json_last_error_msg; use function preg_match; use function preg_replace; use function rtrim; use function sprintf; use function str_replace; use function strlen; use function substr; use function trim; use PHPUnit\Event; use PHPUnit\Event\Code\TestMethod; use PHPUnit\Event\TestData\MoreThanOneDataSetFromDataProviderException; use PHPUnit\Event\TestData\TestDataCollection; use PHPUnit\Framework\InvalidDataProviderException; use PHPUnit\Metadata\DataProvider as DataProviderMetadata; use PHPUnit\Metadata\MetadataCollection; use PHPUnit\Metadata\Parser\Registry as MetadataRegistry; use PHPUnit\Metadata\TestWith; use PHPUnit\Util\Reflection; use ReflectionClass; use ReflectionMethod; use Throwable; use Traversable; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class DataProvider { /** * @psalm-param class-string $className * @psalm-param non-empty-string $methodName * * @throws InvalidDataProviderException */ public function providedData(string $className, string $methodName): ?array { $dataProvider = MetadataRegistry::parser()->forMethod($className, $methodName)->isDataProvider(); $testWith = MetadataRegistry::parser()->forMethod($className, $methodName)->isTestWith(); if ($dataProvider->isEmpty() && $testWith->isEmpty()) { return $this->dataProvidedByTestWithAnnotation($className, $methodName); } if ($dataProvider->isNotEmpty()) { $data = $this->dataProvidedByMethods($className, $methodName, $dataProvider); } else { $data = $this->dataProvidedByMetadata($testWith); } if ($data === []) { throw new InvalidDataProviderException( 'Empty data set provided by data provider', ); } foreach ($data as $key => $value) { if (!is_array($value)) { throw new InvalidDataProviderException( sprintf( 'Data set %s is invalid', is_int($key) ? '#' . $key : '"' . $key . '"', ), ); } } return $data; } /** * @psalm-param class-string $className * @psalm-param non-empty-string $methodName * * @throws InvalidDataProviderException */ private function dataProvidedByMethods(string $className, string $methodName, MetadataCollection $dataProvider): array { $testMethod = new Event\Code\ClassMethod($className, $methodName); $methodsCalled = []; $result = []; foreach ($dataProvider as $_dataProvider) { assert($_dataProvider instanceof DataProviderMetadata); $dataProviderMethod = new Event\Code\ClassMethod($_dataProvider->className(), $_dataProvider->methodName()); Event\Facade::emitter()->dataProviderMethodCalled( $testMethod, $dataProviderMethod, ); $methodsCalled[] = $dataProviderMethod; try { $class = new ReflectionClass($_dataProvider->className()); $method = $class->getMethod($_dataProvider->methodName()); $object = null; if (!$method->isPublic()) { Event\Facade::emitter()->testTriggeredPhpunitDeprecation( $this->valueObjectForTestMethodWithoutTestData( $className, $methodName, ), sprintf( 'Data Provider method %s::%s() is not public', $_dataProvider->className(), $_dataProvider->methodName(), ), ); } if (!$method->isStatic()) { Event\Facade::emitter()->testTriggeredPhpunitDeprecation( $this->valueObjectForTestMethodWithoutTestData( $className, $methodName, ), sprintf( 'Data Provider method %s::%s() is not static', $_dataProvider->className(), $_dataProvider->methodName(), ), ); $object = $class->newInstanceWithoutConstructor(); } if ($method->getNumberOfParameters() === 0) { $data = $method->invoke($object); } else { Event\Facade::emitter()->testTriggeredPhpunitDeprecation( $this->valueObjectForTestMethodWithoutTestData( $className, $methodName, ), sprintf( 'Data Provider method %s::%s() expects an argument', $_dataProvider->className(), $_dataProvider->methodName(), ), ); $data = $method->invoke($object, $_dataProvider->methodName()); } } catch (Throwable $e) { Event\Facade::emitter()->dataProviderMethodFinished( $testMethod, ...$methodsCalled, ); throw new InvalidDataProviderException( $e->getMessage(), $e->getCode(), $e, ); } if ($data instanceof Traversable) { $origData = $data; $data = []; foreach ($origData as $key => $value) { if (is_int($key)) { $data[] = $value; } elseif (array_key_exists($key, $data)) { Event\Facade::emitter()->dataProviderMethodFinished( $testMethod, ...$methodsCalled, ); throw new InvalidDataProviderException( sprintf( 'The key "%s" has already been defined by a previous data provider', $key, ), ); } else { $data[$key] = $value; } } } if (is_array($data)) { $result = array_merge($result, $data); } } Event\Facade::emitter()->dataProviderMethodFinished( $testMethod, ...$methodsCalled, ); return $result; } private function dataProvidedByMetadata(MetadataCollection $testWith): array { $result = []; foreach ($testWith as $_testWith) { assert($_testWith instanceof TestWith); $result[] = $_testWith->data(); } return $result; } /** * @psalm-param class-string $className * * @throws InvalidDataProviderException */ private function dataProvidedByTestWithAnnotation(string $className, string $methodName): ?array { $docComment = (new ReflectionMethod($className, $methodName))->getDocComment(); if (!$docComment) { return null; } $docComment = str_replace("\r\n", "\n", $docComment); $docComment = preg_replace('/\n\s*\*\s?/', "\n", $docComment); $docComment = substr($docComment, 0, -1); $docComment = rtrim($docComment, "\n"); if (!preg_match('/@testWith\s+/', $docComment, $matches, PREG_OFFSET_CAPTURE)) { return null; } $offset = strlen($matches[0][0]) + (int) $matches[0][1]; $annotationContent = substr($docComment, $offset); $data = []; foreach (explode("\n", $annotationContent) as $candidateRow) { $candidateRow = trim($candidateRow); if ($candidateRow[0] !== '[') { break; } $dataSet = json_decode($candidateRow, true); if (json_last_error() !== JSON_ERROR_NONE) { throw new InvalidDataProviderException( 'The data set for the @testWith annotation cannot be parsed: ' . json_last_error_msg(), ); } $data[] = $dataSet; } if (!$data) { throw new InvalidDataProviderException( 'The data set for the @testWith annotation cannot be parsed.', ); } return $data; } /** * @psalm-param class-string $className * @psalm-param non-empty-string $methodName * * @throws MoreThanOneDataSetFromDataProviderException */ private function valueObjectForTestMethodWithoutTestData(string $className, string $methodName): TestMethod { $location = Reflection::sourceLocationFor($className, $methodName); return new TestMethod( $className, $methodName, $location['file'], $location['line'], Event\Code\TestDoxBuilder::fromClassNameAndMethodName( $className, $methodName, ), MetadataRegistry::parser()->forClassAndMethod( $className, $methodName, ), TestDataCollection::fromArray([]), ); } } Api/Dependencies.php 0000644 00000003046 15111216105 0010350 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata\Api; use function assert; use PHPUnit\Framework\ExecutionOrderDependency; use PHPUnit\Metadata\DependsOnClass; use PHPUnit\Metadata\DependsOnMethod; use PHPUnit\Metadata\Parser\Registry; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class Dependencies { /** * @psalm-param class-string $className * @psalm-param non-empty-string $methodName * * @psalm-return list<ExecutionOrderDependency> */ public static function dependencies(string $className, string $methodName): array { $dependencies = []; foreach (Registry::parser()->forClassAndMethod($className, $methodName)->isDepends() as $metadata) { if ($metadata->isDependsOnClass()) { assert($metadata instanceof DependsOnClass); $dependencies[] = ExecutionOrderDependency::forClass($metadata); continue; } assert($metadata instanceof DependsOnMethod); if (empty($metadata->methodName())) { $dependencies[] = ExecutionOrderDependency::invalid(); continue; } $dependencies[] = ExecutionOrderDependency::forMethod($metadata); } return $dependencies; } } Api/Groups.php 0000644 00000006512 15111216105 0007242 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata\Api; use function array_flip; use function array_unique; use function assert; use function strtolower; use function trim; use PHPUnit\Framework\TestSize\TestSize; use PHPUnit\Metadata\Covers; use PHPUnit\Metadata\CoversClass; use PHPUnit\Metadata\CoversFunction; use PHPUnit\Metadata\Group; use PHPUnit\Metadata\Parser\Registry; use PHPUnit\Metadata\Uses; use PHPUnit\Metadata\UsesClass; use PHPUnit\Metadata\UsesFunction; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class Groups { /** * @psalm-param class-string $className * @psalm-param non-empty-string $methodName * * @psalm-return list<string> */ public function groups(string $className, string $methodName, bool $includeVirtual = true): array { $groups = []; foreach (Registry::parser()->forClassAndMethod($className, $methodName)->isGroup() as $group) { assert($group instanceof Group); $groups[] = $group->groupName(); } if ($groups === []) { $groups[] = 'default'; } if (!$includeVirtual) { return array_unique($groups); } foreach (Registry::parser()->forClassAndMethod($className, $methodName) as $metadata) { if ($metadata->isCoversClass() || $metadata->isCoversFunction()) { assert($metadata instanceof CoversClass || $metadata instanceof CoversFunction); $groups[] = '__phpunit_covers_' . $this->canonicalizeName($metadata->asStringForCodeUnitMapper()); continue; } if ($metadata->isCovers()) { assert($metadata instanceof Covers); $groups[] = '__phpunit_covers_' . $this->canonicalizeName($metadata->target()); continue; } if ($metadata->isUsesClass() || $metadata->isUsesFunction()) { assert($metadata instanceof UsesClass || $metadata instanceof UsesFunction); $groups[] = '__phpunit_uses_' . $this->canonicalizeName($metadata->asStringForCodeUnitMapper()); continue; } if ($metadata->isUses()) { assert($metadata instanceof Uses); $groups[] = '__phpunit_uses_' . $this->canonicalizeName($metadata->target()); } } return array_unique($groups); } /** * @psalm-param class-string $className * @psalm-param non-empty-string $methodName */ public function size(string $className, string $methodName): TestSize { $groups = array_flip($this->groups($className, $methodName)); if (isset($groups['large'])) { return TestSize::large(); } if (isset($groups['medium'])) { return TestSize::medium(); } if (isset($groups['small'])) { return TestSize::small(); } return TestSize::unknown(); } private function canonicalizeName(string $name): string { return strtolower(trim($name, '\\')); } } RequiresOperatingSystemFamily.php 0000644 00000002306 15111216105 0013266 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class RequiresOperatingSystemFamily extends Metadata { /** * @psalm-var non-empty-string */ private readonly string $operatingSystemFamily; /** * @psalm-param 0|1 $level * @psalm-param non-empty-string $operatingSystemFamily */ protected function __construct(int $level, string $operatingSystemFamily) { parent::__construct($level); $this->operatingSystemFamily = $operatingSystemFamily; } /** * @psalm-assert-if-true RequiresOperatingSystemFamily $this */ public function isRequiresOperatingSystemFamily(): bool { return true; } /** * @psalm-return non-empty-string */ public function operatingSystemFamily(): string { return $this->operatingSystemFamily; } } ExcludeGlobalVariableFromBackup.php 0000644 00000002267 15111216105 0013407 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class ExcludeGlobalVariableFromBackup extends Metadata { /** * @psalm-var non-empty-string */ private readonly string $globalVariableName; /** * @psalm-param 0|1 $level * @psalm-param non-empty-string $globalVariableName */ protected function __construct(int $level, string $globalVariableName) { parent::__construct($level); $this->globalVariableName = $globalVariableName; } /** * @psalm-assert-if-true ExcludeGlobalVariableFromBackup $this */ public function isExcludeGlobalVariableFromBackup(): bool { return true; } /** * @psalm-return non-empty-string */ public function globalVariableName(): string { return $this->globalVariableName; } } RequiresFunction.php 0000644 00000002140 15111216106 0010551 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class RequiresFunction extends Metadata { /** * @psalm-var non-empty-string */ private readonly string $functionName; /** * @psalm-param 0|1 $level * @psalm-param non-empty-string $functionName */ protected function __construct(int $level, string $functionName) { parent::__construct($level); $this->functionName = $functionName; } /** * @psalm-assert-if-true RequiresFunction $this */ public function isRequiresFunction(): bool { return true; } /** * @psalm-return non-empty-string */ public function functionName(): string { return $this->functionName; } } IgnoreClassForCodeCoverage.php 0000644 00000002250 15111216106 0012375 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit * * @deprecated https://github.com/sebastianbergmann/phpunit/issues/5513 */ final class IgnoreClassForCodeCoverage extends Metadata { /** * @psalm-var class-string */ private readonly string $className; /** * @psalm-param 0|1 $level * @psalm-param class-string $className */ protected function __construct(int $level, string $className) { parent::__construct($level); $this->className = $className; } /** * @psalm-assert-if-true IgnoreClassForCodeCoverage $this */ public function isIgnoreClassForCodeCoverage(): bool { return true; } /** * @psalm-return class-string */ public function className(): string { return $this->className; } } After.php 0000644 00000001107 15111216106 0006307 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class After extends Metadata { /** * @psalm-assert-if-true After $this */ public function isAfter(): bool { return true; } } Parser/Annotation/DocBlock.php 0000644 00000022622 15111216106 0012301 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata\Annotation\Parser; use function array_filter; use function array_map; use function array_merge; use function array_values; use function count; use function preg_match; use function preg_match_all; use function preg_replace; use function preg_split; use function realpath; use function substr; use function trim; use PharIo\Version\Exception as PharIoVersionException; use PharIo\Version\VersionConstraintParser; use PHPUnit\Metadata\AnnotationsAreNotSupportedForInternalClassesException; use PHPUnit\Metadata\InvalidVersionRequirementException; use ReflectionClass; use ReflectionFunctionAbstract; use ReflectionMethod; /** * This is an abstraction around a PHPUnit-specific docBlock, * allowing us to ask meaningful questions about a specific * reflection symbol. * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class DocBlock { private const REGEX_REQUIRES_VERSION = '/@requires\s+(?P<name>PHP(?:Unit)?)\s+(?P<operator>[<>=!]{0,2})\s*(?P<version>[\d\.-]+(dev|(RC|alpha|beta)[\d\.])?)[ \t]*\r?$/m'; private const REGEX_REQUIRES_VERSION_CONSTRAINT = '/@requires\s+(?P<name>PHP(?:Unit)?)\s+(?P<constraint>[\d\t \-.|~^]+)[ \t]*\r?$/m'; private const REGEX_REQUIRES_OS = '/@requires\s+(?P<name>OS(?:FAMILY)?)\s+(?P<value>.+?)[ \t]*\r?$/m'; private const REGEX_REQUIRES_SETTING = '/@requires\s+(?P<name>setting)\s+(?P<setting>([^ ]+?))\s*(?P<value>[\w\.-]+[\w\.]?)?[ \t]*\r?$/m'; private const REGEX_REQUIRES = '/@requires\s+(?P<name>function|extension)\s+(?P<value>([^\s<>=!]+))\s*(?P<operator>[<>=!]{0,2})\s*(?P<version>[\d\.-]+[\d\.]?)?[ \t]*\r?$/m'; private readonly string $docComment; /** * @psalm-var array<string, array<int, string>> pre-parsed annotations indexed by name and occurrence index */ private readonly array $symbolAnnotations; /** * @psalm-var null|(array{ * __OFFSET: array<string, int>&array{__FILE: string}, * setting?: array<string, string>, * extension_versions?: array<string, array{version: string, operator: string}> * }&array< * string, * string|array{version: string, operator: string}|array{constraint: string}|array<int|string, string> * >) */ private ?array $parsedRequirements = null; private readonly int $startLine; private readonly string $fileName; /** * @throws AnnotationsAreNotSupportedForInternalClassesException */ public static function ofClass(ReflectionClass $class): self { if ($class->isInternal()) { throw new AnnotationsAreNotSupportedForInternalClassesException($class->getName()); } return new self( (string) $class->getDocComment(), self::extractAnnotationsFromReflector($class), $class->getStartLine(), $class->getFileName(), ); } /** * @throws AnnotationsAreNotSupportedForInternalClassesException */ public static function ofMethod(ReflectionMethod $method): self { if ($method->getDeclaringClass()->isInternal()) { throw new AnnotationsAreNotSupportedForInternalClassesException($method->getDeclaringClass()->getName()); } return new self( (string) $method->getDocComment(), self::extractAnnotationsFromReflector($method), $method->getStartLine(), $method->getFileName(), ); } /** * Note: we do not preserve an instance of the reflection object, since it cannot be safely (de-)serialized. * * @param array<string, array<int, string>> $symbolAnnotations */ private function __construct(string $docComment, array $symbolAnnotations, int $startLine, string $fileName) { $this->docComment = $docComment; $this->symbolAnnotations = $symbolAnnotations; $this->startLine = $startLine; $this->fileName = $fileName; } /** * @psalm-return array{ * __OFFSET: array<string, int>&array{__FILE: string}, * setting?: array<string, string>, * extension_versions?: array<string, array{version: string, operator: string}> * }&array< * string, * string|array{version: string, operator: string}|array{constraint: string}|array<int|string, string> * > */ public function requirements(): array { if ($this->parsedRequirements !== null) { return $this->parsedRequirements; } $offset = $this->startLine; $requires = []; $recordedSettings = []; $extensionVersions = []; $recordedOffsets = [ '__FILE' => realpath($this->fileName), ]; // Trim docblock markers, split it into lines and rewind offset to start of docblock $lines = preg_replace(['#^/\*{2}#', '#\*/$#'], '', preg_split('/\r\n|\r|\n/', $this->docComment)); $offset -= count($lines); foreach ($lines as $line) { if (preg_match(self::REGEX_REQUIRES_OS, $line, $matches)) { $requires[$matches['name']] = $matches['value']; $recordedOffsets[$matches['name']] = $offset; } if (preg_match(self::REGEX_REQUIRES_VERSION, $line, $matches)) { $requires[$matches['name']] = [ 'version' => $matches['version'], 'operator' => $matches['operator'], ]; $recordedOffsets[$matches['name']] = $offset; } if (preg_match(self::REGEX_REQUIRES_VERSION_CONSTRAINT, $line, $matches)) { if (!empty($requires[$matches['name']])) { $offset++; continue; } try { $versionConstraintParser = new VersionConstraintParser; $requires[$matches['name'] . '_constraint'] = [ 'constraint' => $versionConstraintParser->parse(trim($matches['constraint'])), ]; $recordedOffsets[$matches['name'] . '_constraint'] = $offset; } catch (PharIoVersionException $e) { throw new InvalidVersionRequirementException( $e->getMessage(), $e->getCode(), $e, ); } } if (preg_match(self::REGEX_REQUIRES_SETTING, $line, $matches)) { $recordedSettings[$matches['setting']] = $matches['value']; $recordedOffsets['__SETTING_' . $matches['setting']] = $offset; } if (preg_match(self::REGEX_REQUIRES, $line, $matches)) { $name = $matches['name'] . 's'; if (!isset($requires[$name])) { $requires[$name] = []; } $requires[$name][] = $matches['value']; $recordedOffsets[$matches['name'] . '_' . $matches['value']] = $offset; if ($name === 'extensions' && !empty($matches['version'])) { $extensionVersions[$matches['value']] = [ 'version' => $matches['version'], 'operator' => $matches['operator'], ]; } } $offset++; } return $this->parsedRequirements = array_merge( $requires, ['__OFFSET' => $recordedOffsets], array_filter( [ 'setting' => $recordedSettings, 'extension_versions' => $extensionVersions, ], ), ); } public function symbolAnnotations(): array { return $this->symbolAnnotations; } /** * @psalm-return array<string, array<int, string>> */ private static function parseDocBlock(string $docBlock): array { // Strip away the docblock header and footer to ease parsing of one line annotations $docBlock = substr($docBlock, 3, -2); $annotations = []; if (preg_match_all('/@(?P<name>[A-Za-z_-]+)(?:[ \t]+(?P<value>.*?))?[ \t]*\r?$/m', $docBlock, $matches)) { $numMatches = count($matches[0]); for ($i = 0; $i < $numMatches; $i++) { $annotations[$matches['name'][$i]][] = $matches['value'][$i]; } } return $annotations; } private static function extractAnnotationsFromReflector(ReflectionClass|ReflectionFunctionAbstract $reflector): array { $annotations = []; if ($reflector instanceof ReflectionClass) { $annotations = array_merge( $annotations, ...array_map( static fn (ReflectionClass $trait): array => self::parseDocBlock((string) $trait->getDocComment()), array_values($reflector->getTraits()), ), ); } return array_merge( $annotations, self::parseDocBlock((string) $reflector->getDocComment()), ); } } Parser/Annotation/Registry.php 0000644 00000005576 15111216106 0012442 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata\Annotation\Parser; use function array_key_exists; use PHPUnit\Metadata\AnnotationsAreNotSupportedForInternalClassesException; use PHPUnit\Metadata\ReflectionException; use ReflectionClass; use ReflectionMethod; /** * Reflection information, and therefore DocBlock information, is static within * a single PHP process. It is therefore okay to use a Singleton registry here. * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class Registry { private static ?Registry $instance = null; /** * @psalm-var array<string, DocBlock> indexed by class name */ private array $classDocBlocks = []; /** * @psalm-var array<string, array<string, DocBlock>> indexed by class name and method name */ private array $methodDocBlocks = []; public static function getInstance(): self { return self::$instance ?? self::$instance = new self; } private function __construct() { } /** * @psalm-param class-string $class * * @throws AnnotationsAreNotSupportedForInternalClassesException * @throws ReflectionException */ public function forClassName(string $class): DocBlock { if (array_key_exists($class, $this->classDocBlocks)) { return $this->classDocBlocks[$class]; } try { $reflection = new ReflectionClass($class); // @codeCoverageIgnoreStart } catch (\ReflectionException $e) { throw new ReflectionException( $e->getMessage(), $e->getCode(), $e, ); } // @codeCoverageIgnoreEnd return $this->classDocBlocks[$class] = DocBlock::ofClass($reflection); } /** * @psalm-param class-string $classInHierarchy * * @throws AnnotationsAreNotSupportedForInternalClassesException * @throws ReflectionException */ public function forMethod(string $classInHierarchy, string $method): DocBlock { if (isset($this->methodDocBlocks[$classInHierarchy][$method])) { return $this->methodDocBlocks[$classInHierarchy][$method]; } try { $reflection = new ReflectionMethod($classInHierarchy, $method); // @codeCoverageIgnoreStart } catch (\ReflectionException $e) { throw new ReflectionException( $e->getMessage(), $e->getCode(), $e, ); } // @codeCoverageIgnoreEnd return $this->methodDocBlocks[$classInHierarchy][$method] = DocBlock::ofMethod($reflection); } } Parser/AttributeParser.php 0000644 00000055167 15111216106 0011641 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata\Parser; use const JSON_THROW_ON_ERROR; use function assert; use function json_decode; use function str_starts_with; use PHPUnit\Framework\Attributes\After; use PHPUnit\Framework\Attributes\AfterClass; use PHPUnit\Framework\Attributes\BackupGlobals; use PHPUnit\Framework\Attributes\BackupStaticProperties; use PHPUnit\Framework\Attributes\Before; use PHPUnit\Framework\Attributes\BeforeClass; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\CoversFunction; use PHPUnit\Framework\Attributes\CoversNothing; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\DataProviderExternal; use PHPUnit\Framework\Attributes\Depends; use PHPUnit\Framework\Attributes\DependsExternal; use PHPUnit\Framework\Attributes\DependsExternalUsingDeepClone; use PHPUnit\Framework\Attributes\DependsExternalUsingShallowClone; use PHPUnit\Framework\Attributes\DependsOnClass; use PHPUnit\Framework\Attributes\DependsOnClassUsingDeepClone; use PHPUnit\Framework\Attributes\DependsOnClassUsingShallowClone; use PHPUnit\Framework\Attributes\DependsUsingDeepClone; use PHPUnit\Framework\Attributes\DependsUsingShallowClone; use PHPUnit\Framework\Attributes\DoesNotPerformAssertions; use PHPUnit\Framework\Attributes\ExcludeGlobalVariableFromBackup; use PHPUnit\Framework\Attributes\ExcludeStaticPropertyFromBackup; use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\Attributes\IgnoreClassForCodeCoverage; use PHPUnit\Framework\Attributes\IgnoreFunctionForCodeCoverage; use PHPUnit\Framework\Attributes\IgnoreMethodForCodeCoverage; use PHPUnit\Framework\Attributes\Large; use PHPUnit\Framework\Attributes\Medium; use PHPUnit\Framework\Attributes\PostCondition; use PHPUnit\Framework\Attributes\PreCondition; use PHPUnit\Framework\Attributes\PreserveGlobalState; use PHPUnit\Framework\Attributes\RequiresFunction; use PHPUnit\Framework\Attributes\RequiresMethod; use PHPUnit\Framework\Attributes\RequiresOperatingSystem; use PHPUnit\Framework\Attributes\RequiresOperatingSystemFamily; use PHPUnit\Framework\Attributes\RequiresPhp; use PHPUnit\Framework\Attributes\RequiresPhpExtension; use PHPUnit\Framework\Attributes\RequiresPhpunit; use PHPUnit\Framework\Attributes\RequiresSetting; use PHPUnit\Framework\Attributes\RunClassInSeparateProcess; use PHPUnit\Framework\Attributes\RunInSeparateProcess; use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses; use PHPUnit\Framework\Attributes\Small; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\Attributes\TestDox; use PHPUnit\Framework\Attributes\TestWith; use PHPUnit\Framework\Attributes\TestWithJson; use PHPUnit\Framework\Attributes\Ticket; use PHPUnit\Framework\Attributes\UsesClass; use PHPUnit\Framework\Attributes\UsesFunction; use PHPUnit\Framework\Attributes\WithoutErrorHandler; use PHPUnit\Metadata\Metadata; use PHPUnit\Metadata\MetadataCollection; use PHPUnit\Metadata\Version\ConstraintRequirement; use ReflectionClass; use ReflectionMethod; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class AttributeParser implements Parser { /** * @psalm-param class-string $className */ public function forClass(string $className): MetadataCollection { $result = []; foreach ((new ReflectionClass($className))->getAttributes() as $attribute) { if (!str_starts_with($attribute->getName(), 'PHPUnit\\Framework\\Attributes\\')) { continue; } $attributeInstance = $attribute->newInstance(); switch ($attribute->getName()) { case BackupGlobals::class: assert($attributeInstance instanceof BackupGlobals); $result[] = Metadata::backupGlobalsOnClass($attributeInstance->enabled()); break; case BackupStaticProperties::class: assert($attributeInstance instanceof BackupStaticProperties); $result[] = Metadata::backupStaticPropertiesOnClass($attributeInstance->enabled()); break; case CoversClass::class: assert($attributeInstance instanceof CoversClass); $result[] = Metadata::coversClass($attributeInstance->className()); break; case CoversFunction::class: assert($attributeInstance instanceof CoversFunction); $result[] = Metadata::coversFunction($attributeInstance->functionName()); break; case CoversNothing::class: $result[] = Metadata::coversNothingOnClass(); break; case DoesNotPerformAssertions::class: $result[] = Metadata::doesNotPerformAssertionsOnClass(); break; case ExcludeGlobalVariableFromBackup::class: assert($attributeInstance instanceof ExcludeGlobalVariableFromBackup); $result[] = Metadata::excludeGlobalVariableFromBackupOnClass($attributeInstance->globalVariableName()); break; case ExcludeStaticPropertyFromBackup::class: assert($attributeInstance instanceof ExcludeStaticPropertyFromBackup); $result[] = Metadata::excludeStaticPropertyFromBackupOnClass( $attributeInstance->className(), $attributeInstance->propertyName(), ); break; case Group::class: assert($attributeInstance instanceof Group); $result[] = Metadata::groupOnClass($attributeInstance->name()); break; case Large::class: $result[] = Metadata::groupOnClass('large'); break; case Medium::class: $result[] = Metadata::groupOnClass('medium'); break; case IgnoreClassForCodeCoverage::class: assert($attributeInstance instanceof IgnoreClassForCodeCoverage); $result[] = Metadata::ignoreClassForCodeCoverage($attributeInstance->className()); break; case IgnoreMethodForCodeCoverage::class: assert($attributeInstance instanceof IgnoreMethodForCodeCoverage); $result[] = Metadata::ignoreMethodForCodeCoverage($attributeInstance->className(), $attributeInstance->methodName()); break; case IgnoreFunctionForCodeCoverage::class: assert($attributeInstance instanceof IgnoreFunctionForCodeCoverage); $result[] = Metadata::ignoreFunctionForCodeCoverage($attributeInstance->functionName()); break; case PreserveGlobalState::class: assert($attributeInstance instanceof PreserveGlobalState); $result[] = Metadata::preserveGlobalStateOnClass($attributeInstance->enabled()); break; case RequiresMethod::class: assert($attributeInstance instanceof RequiresMethod); $result[] = Metadata::requiresMethodOnClass( $attributeInstance->className(), $attributeInstance->methodName(), ); break; case RequiresFunction::class: assert($attributeInstance instanceof RequiresFunction); $result[] = Metadata::requiresFunctionOnClass($attributeInstance->functionName()); break; case RequiresOperatingSystem::class: assert($attributeInstance instanceof RequiresOperatingSystem); $result[] = Metadata::requiresOperatingSystemOnClass($attributeInstance->regularExpression()); break; case RequiresOperatingSystemFamily::class: assert($attributeInstance instanceof RequiresOperatingSystemFamily); $result[] = Metadata::requiresOperatingSystemFamilyOnClass($attributeInstance->operatingSystemFamily()); break; case RequiresPhp::class: assert($attributeInstance instanceof RequiresPhp); $result[] = Metadata::requiresPhpOnClass( ConstraintRequirement::from( $attributeInstance->versionRequirement(), ), ); break; case RequiresPhpExtension::class: assert($attributeInstance instanceof RequiresPhpExtension); $versionConstraint = null; $versionRequirement = $attributeInstance->versionRequirement(); if ($versionRequirement !== null) { $versionConstraint = ConstraintRequirement::from($versionRequirement); } $result[] = Metadata::requiresPhpExtensionOnClass( $attributeInstance->extension(), $versionConstraint, ); break; case RequiresPhpunit::class: assert($attributeInstance instanceof RequiresPhpunit); $result[] = Metadata::requiresPhpunitOnClass( ConstraintRequirement::from( $attributeInstance->versionRequirement(), ), ); break; case RequiresSetting::class: assert($attributeInstance instanceof RequiresSetting); $result[] = Metadata::requiresSettingOnClass( $attributeInstance->setting(), $attributeInstance->value(), ); break; case RunClassInSeparateProcess::class: $result[] = Metadata::runClassInSeparateProcess(); break; case RunTestsInSeparateProcesses::class: $result[] = Metadata::runTestsInSeparateProcesses(); break; case Small::class: $result[] = Metadata::groupOnClass('small'); break; case TestDox::class: assert($attributeInstance instanceof TestDox); $result[] = Metadata::testDoxOnClass($attributeInstance->text()); break; case Ticket::class: assert($attributeInstance instanceof Ticket); $result[] = Metadata::groupOnClass($attributeInstance->text()); break; case UsesClass::class: assert($attributeInstance instanceof UsesClass); $result[] = Metadata::usesClass($attributeInstance->className()); break; case UsesFunction::class: assert($attributeInstance instanceof UsesFunction); $result[] = Metadata::usesFunction($attributeInstance->functionName()); break; } } return MetadataCollection::fromArray($result); } /** * @psalm-param class-string $className * @psalm-param non-empty-string $methodName */ public function forMethod(string $className, string $methodName): MetadataCollection { $result = []; foreach ((new ReflectionMethod($className, $methodName))->getAttributes() as $attribute) { if (!str_starts_with($attribute->getName(), 'PHPUnit\\Framework\\Attributes\\')) { continue; } $attributeInstance = $attribute->newInstance(); switch ($attribute->getName()) { case After::class: $result[] = Metadata::after(); break; case AfterClass::class: $result[] = Metadata::afterClass(); break; case BackupGlobals::class: assert($attributeInstance instanceof BackupGlobals); $result[] = Metadata::backupGlobalsOnMethod($attributeInstance->enabled()); break; case BackupStaticProperties::class: assert($attributeInstance instanceof BackupStaticProperties); $result[] = Metadata::backupStaticPropertiesOnMethod($attributeInstance->enabled()); break; case Before::class: $result[] = Metadata::before(); break; case BeforeClass::class: $result[] = Metadata::beforeClass(); break; case CoversNothing::class: $result[] = Metadata::coversNothingOnMethod(); break; case DataProvider::class: assert($attributeInstance instanceof DataProvider); $result[] = Metadata::dataProvider($className, $attributeInstance->methodName()); break; case DataProviderExternal::class: assert($attributeInstance instanceof DataProviderExternal); $result[] = Metadata::dataProvider($attributeInstance->className(), $attributeInstance->methodName()); break; case Depends::class: assert($attributeInstance instanceof Depends); $result[] = Metadata::dependsOnMethod($className, $attributeInstance->methodName(), false, false); break; case DependsUsingDeepClone::class: assert($attributeInstance instanceof DependsUsingDeepClone); $result[] = Metadata::dependsOnMethod($className, $attributeInstance->methodName(), true, false); break; case DependsUsingShallowClone::class: assert($attributeInstance instanceof DependsUsingShallowClone); $result[] = Metadata::dependsOnMethod($className, $attributeInstance->methodName(), false, true); break; case DependsExternal::class: assert($attributeInstance instanceof DependsExternal); $result[] = Metadata::dependsOnMethod($attributeInstance->className(), $attributeInstance->methodName(), false, false); break; case DependsExternalUsingDeepClone::class: assert($attributeInstance instanceof DependsExternalUsingDeepClone); $result[] = Metadata::dependsOnMethod($attributeInstance->className(), $attributeInstance->methodName(), true, false); break; case DependsExternalUsingShallowClone::class: assert($attributeInstance instanceof DependsExternalUsingShallowClone); $result[] = Metadata::dependsOnMethod($attributeInstance->className(), $attributeInstance->methodName(), false, true); break; case DependsOnClass::class: assert($attributeInstance instanceof DependsOnClass); $result[] = Metadata::dependsOnClass($attributeInstance->className(), false, false); break; case DependsOnClassUsingDeepClone::class: assert($attributeInstance instanceof DependsOnClassUsingDeepClone); $result[] = Metadata::dependsOnClass($attributeInstance->className(), true, false); break; case DependsOnClassUsingShallowClone::class: assert($attributeInstance instanceof DependsOnClassUsingShallowClone); $result[] = Metadata::dependsOnClass($attributeInstance->className(), false, true); break; case DoesNotPerformAssertions::class: assert($attributeInstance instanceof DoesNotPerformAssertions); $result[] = Metadata::doesNotPerformAssertionsOnMethod(); break; case ExcludeGlobalVariableFromBackup::class: assert($attributeInstance instanceof ExcludeGlobalVariableFromBackup); $result[] = Metadata::excludeGlobalVariableFromBackupOnMethod($attributeInstance->globalVariableName()); break; case ExcludeStaticPropertyFromBackup::class: assert($attributeInstance instanceof ExcludeStaticPropertyFromBackup); $result[] = Metadata::excludeStaticPropertyFromBackupOnMethod( $attributeInstance->className(), $attributeInstance->propertyName(), ); break; case Group::class: assert($attributeInstance instanceof Group); $result[] = Metadata::groupOnMethod($attributeInstance->name()); break; case PostCondition::class: $result[] = Metadata::postCondition(); break; case PreCondition::class: $result[] = Metadata::preCondition(); break; case PreserveGlobalState::class: assert($attributeInstance instanceof PreserveGlobalState); $result[] = Metadata::preserveGlobalStateOnMethod($attributeInstance->enabled()); break; case RequiresMethod::class: assert($attributeInstance instanceof RequiresMethod); $result[] = Metadata::requiresMethodOnMethod( $attributeInstance->className(), $attributeInstance->methodName(), ); break; case RequiresFunction::class: assert($attributeInstance instanceof RequiresFunction); $result[] = Metadata::requiresFunctionOnMethod($attributeInstance->functionName()); break; case RequiresOperatingSystem::class: assert($attributeInstance instanceof RequiresOperatingSystem); $result[] = Metadata::requiresOperatingSystemOnMethod($attributeInstance->regularExpression()); break; case RequiresOperatingSystemFamily::class: assert($attributeInstance instanceof RequiresOperatingSystemFamily); $result[] = Metadata::requiresOperatingSystemFamilyOnMethod($attributeInstance->operatingSystemFamily()); break; case RequiresPhp::class: assert($attributeInstance instanceof RequiresPhp); $result[] = Metadata::requiresPhpOnMethod( ConstraintRequirement::from( $attributeInstance->versionRequirement(), ), ); break; case RequiresPhpExtension::class: assert($attributeInstance instanceof RequiresPhpExtension); $versionConstraint = null; $versionRequirement = $attributeInstance->versionRequirement(); if ($versionRequirement !== null) { $versionConstraint = ConstraintRequirement::from($versionRequirement); } $result[] = Metadata::requiresPhpExtensionOnMethod( $attributeInstance->extension(), $versionConstraint, ); break; case RequiresPhpunit::class: assert($attributeInstance instanceof RequiresPhpunit); $result[] = Metadata::requiresPhpunitOnMethod( ConstraintRequirement::from( $attributeInstance->versionRequirement(), ), ); break; case RequiresSetting::class: assert($attributeInstance instanceof RequiresSetting); $result[] = Metadata::requiresSettingOnMethod( $attributeInstance->setting(), $attributeInstance->value(), ); break; case RunInSeparateProcess::class: $result[] = Metadata::runInSeparateProcess(); break; case Test::class: $result[] = Metadata::test(); break; case TestDox::class: assert($attributeInstance instanceof TestDox); $result[] = Metadata::testDoxOnMethod($attributeInstance->text()); break; case TestWith::class: assert($attributeInstance instanceof TestWith); $result[] = Metadata::testWith($attributeInstance->data()); break; case TestWithJson::class: assert($attributeInstance instanceof TestWithJson); $result[] = Metadata::testWith(json_decode($attributeInstance->json(), true, 512, JSON_THROW_ON_ERROR)); break; case Ticket::class: assert($attributeInstance instanceof Ticket); $result[] = Metadata::groupOnMethod($attributeInstance->text()); break; case WithoutErrorHandler::class: assert($attributeInstance instanceof WithoutErrorHandler); $result[] = Metadata::withoutErrorHandler(); break; } } return MetadataCollection::fromArray($result); } /** * @psalm-param class-string $className * @psalm-param non-empty-string $methodName */ public function forClassAndMethod(string $className, string $methodName): MetadataCollection { return $this->forClass($className)->mergeWith( $this->forMethod($className, $methodName), ); } } Parser/CachingParser.php 0000644 00000004225 15111216106 0011217 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata\Parser; use PHPUnit\Metadata\MetadataCollection; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class CachingParser implements Parser { private readonly Parser $reader; private array $classCache = []; private array $methodCache = []; private array $classAndMethodCache = []; public function __construct(Parser $reader) { $this->reader = $reader; } /** * @psalm-param class-string $className */ public function forClass(string $className): MetadataCollection { if (isset($this->classCache[$className])) { return $this->classCache[$className]; } $this->classCache[$className] = $this->reader->forClass($className); return $this->classCache[$className]; } /** * @psalm-param class-string $className * @psalm-param non-empty-string $methodName */ public function forMethod(string $className, string $methodName): MetadataCollection { $key = $className . '::' . $methodName; if (isset($this->methodCache[$key])) { return $this->methodCache[$key]; } $this->methodCache[$key] = $this->reader->forMethod($className, $methodName); return $this->methodCache[$key]; } /** * @psalm-param class-string $className * @psalm-param non-empty-string $methodName */ public function forClassAndMethod(string $className, string $methodName): MetadataCollection { $key = $className . '::' . $methodName; if (isset($this->classAndMethodCache[$key])) { return $this->classAndMethodCache[$key]; } $this->classAndMethodCache[$key] = $this->forClass($className)->mergeWith( $this->forMethod($className, $methodName), ); return $this->classAndMethodCache[$key]; } } Parser/Parser.php 0000644 00000001732 15111216106 0007742 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata\Parser; use PHPUnit\Metadata\MetadataCollection; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit */ interface Parser { /** * @psalm-param class-string $className */ public function forClass(string $className): MetadataCollection; /** * @psalm-param class-string $className * @psalm-param non-empty-string $methodName */ public function forMethod(string $className, string $methodName): MetadataCollection; /** * @psalm-param class-string $className * @psalm-param non-empty-string $methodName */ public function forClassAndMethod(string $className, string $methodName): MetadataCollection; } Parser/AnnotationParser.php 0000644 00000043203 15111216107 0011775 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata\Parser; use function array_merge; use function assert; use function count; use function explode; use function method_exists; use function preg_replace; use function rtrim; use function str_contains; use function str_starts_with; use function strlen; use function substr; use function trim; use PHPUnit\Metadata\Annotation\Parser\Registry as AnnotationRegistry; use PHPUnit\Metadata\AnnotationsAreNotSupportedForInternalClassesException; use PHPUnit\Metadata\Metadata; use PHPUnit\Metadata\MetadataCollection; use PHPUnit\Metadata\ReflectionException; use PHPUnit\Metadata\Version\ComparisonRequirement; use PHPUnit\Metadata\Version\ConstraintRequirement; use PHPUnit\Util\InvalidVersionOperatorException; use PHPUnit\Util\VersionComparisonOperator; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class AnnotationParser implements Parser { /** * @psalm-param class-string $className * * @throws AnnotationsAreNotSupportedForInternalClassesException * @throws InvalidVersionOperatorException * @throws ReflectionException */ public function forClass(string $className): MetadataCollection { $result = []; foreach (AnnotationRegistry::getInstance()->forClassName($className)->symbolAnnotations() as $annotation => $values) { switch ($annotation) { case 'backupGlobals': $result[] = Metadata::backupGlobalsOnClass($this->stringToBool($values[0])); break; case 'backupStaticAttributes': case 'backupStaticProperties': $result[] = Metadata::backupStaticPropertiesOnClass($this->stringToBool($values[0])); break; case 'covers': foreach ($values as $value) { $value = $this->cleanUpCoversOrUsesTarget($value); $result[] = Metadata::coversOnClass($value); } break; case 'coversDefaultClass': foreach ($values as $value) { $result[] = Metadata::coversDefaultClass($value); } break; case 'coversNothing': $result[] = Metadata::coversNothingOnClass(); break; case 'doesNotPerformAssertions': $result[] = Metadata::doesNotPerformAssertionsOnClass(); break; case 'group': case 'ticket': foreach ($values as $value) { $result[] = Metadata::groupOnClass($value); } break; case 'large': $result[] = Metadata::groupOnClass('large'); break; case 'medium': $result[] = Metadata::groupOnClass('medium'); break; case 'preserveGlobalState': $result[] = Metadata::preserveGlobalStateOnClass($this->stringToBool($values[0])); break; case 'runClassInSeparateProcess': $result[] = Metadata::runClassInSeparateProcess(); break; case 'runTestsInSeparateProcesses': $result[] = Metadata::runTestsInSeparateProcesses(); break; case 'small': $result[] = Metadata::groupOnClass('small'); break; case 'testdox': $result[] = Metadata::testDoxOnClass($values[0]); break; case 'uses': foreach ($values as $value) { $value = $this->cleanUpCoversOrUsesTarget($value); $result[] = Metadata::usesOnClass($value); } break; case 'usesDefaultClass': foreach ($values as $value) { $result[] = Metadata::usesDefaultClass($value); } break; } } $result = array_merge( $result, $this->parseRequirements( AnnotationRegistry::getInstance()->forClassName($className)->requirements(), 'class', ), ); return MetadataCollection::fromArray($result); } /** * @psalm-param class-string $className * @psalm-param non-empty-string $methodName * * @throws AnnotationsAreNotSupportedForInternalClassesException * @throws InvalidVersionOperatorException * @throws ReflectionException */ public function forMethod(string $className, string $methodName): MetadataCollection { $result = []; foreach (AnnotationRegistry::getInstance()->forMethod($className, $methodName)->symbolAnnotations() as $annotation => $values) { switch ($annotation) { case 'after': $result[] = Metadata::after(); break; case 'afterClass': $result[] = Metadata::afterClass(); break; case 'backupGlobals': $result[] = Metadata::backupGlobalsOnMethod($this->stringToBool($values[0])); break; case 'backupStaticAttributes': case 'backupStaticProperties': $result[] = Metadata::backupStaticPropertiesOnMethod($this->stringToBool($values[0])); break; case 'before': $result[] = Metadata::before(); break; case 'beforeClass': $result[] = Metadata::beforeClass(); break; case 'covers': foreach ($values as $value) { $value = $this->cleanUpCoversOrUsesTarget($value); $result[] = Metadata::coversOnMethod($value); } break; case 'coversNothing': $result[] = Metadata::coversNothingOnMethod(); break; case 'dataProvider': foreach ($values as $value) { $value = rtrim($value, " ()\n\r\t\v\x00"); if (str_contains($value, '::')) { $result[] = Metadata::dataProvider(...explode('::', $value)); continue; } $result[] = Metadata::dataProvider($className, $value); } break; case 'depends': foreach ($values as $value) { $deepClone = false; $shallowClone = false; if (str_starts_with($value, 'clone ')) { $deepClone = true; $value = substr($value, strlen('clone ')); } elseif (str_starts_with($value, '!clone ')) { $value = substr($value, strlen('!clone ')); } elseif (str_starts_with($value, 'shallowClone ')) { $shallowClone = true; $value = substr($value, strlen('shallowClone ')); } elseif (str_starts_with($value, '!shallowClone ')) { $value = substr($value, strlen('!shallowClone ')); } if (str_contains($value, '::')) { [$_className, $_methodName] = explode('::', $value); assert($_className !== ''); assert($_methodName !== ''); if ($_methodName === 'class') { $result[] = Metadata::dependsOnClass($_className, $deepClone, $shallowClone); continue; } $result[] = Metadata::dependsOnMethod($_className, $_methodName, $deepClone, $shallowClone); continue; } $result[] = Metadata::dependsOnMethod($className, $value, $deepClone, $shallowClone); } break; case 'doesNotPerformAssertions': $result[] = Metadata::doesNotPerformAssertionsOnMethod(); break; case 'excludeGlobalVariableFromBackup': foreach ($values as $value) { $result[] = Metadata::excludeGlobalVariableFromBackupOnMethod($value); } break; case 'excludeStaticPropertyFromBackup': foreach ($values as $value) { $tmp = explode(' ', $value); if (count($tmp) !== 2) { continue; } $result[] = Metadata::excludeStaticPropertyFromBackupOnMethod( trim($tmp[0]), trim($tmp[1]), ); } break; case 'group': case 'ticket': foreach ($values as $value) { $result[] = Metadata::groupOnMethod($value); } break; case 'large': $result[] = Metadata::groupOnMethod('large'); break; case 'medium': $result[] = Metadata::groupOnMethod('medium'); break; case 'postCondition': $result[] = Metadata::postCondition(); break; case 'preCondition': $result[] = Metadata::preCondition(); break; case 'preserveGlobalState': $result[] = Metadata::preserveGlobalStateOnMethod($this->stringToBool($values[0])); break; case 'runInSeparateProcess': $result[] = Metadata::runInSeparateProcess(); break; case 'small': $result[] = Metadata::groupOnMethod('small'); break; case 'test': $result[] = Metadata::test(); break; case 'testdox': $result[] = Metadata::testDoxOnMethod($values[0]); break; case 'uses': foreach ($values as $value) { $value = $this->cleanUpCoversOrUsesTarget($value); $result[] = Metadata::usesOnMethod($value); } break; } } if (method_exists($className, $methodName)) { $result = array_merge( $result, $this->parseRequirements( AnnotationRegistry::getInstance()->forMethod($className, $methodName)->requirements(), 'method', ), ); } return MetadataCollection::fromArray($result); } /** * @psalm-param class-string $className * @psalm-param non-empty-string $methodName * * @throws AnnotationsAreNotSupportedForInternalClassesException * @throws InvalidVersionOperatorException * @throws ReflectionException */ public function forClassAndMethod(string $className, string $methodName): MetadataCollection { return $this->forClass($className)->mergeWith( $this->forMethod($className, $methodName), ); } private function stringToBool(string $value): bool { if ($value === 'enabled') { return true; } return false; } private function cleanUpCoversOrUsesTarget(string $value): string { $value = preg_replace('/[\s()]+$/', '', $value); return explode(' ', $value, 2)[0]; } /** * @psalm-return list<Metadata> * * @throws InvalidVersionOperatorException */ private function parseRequirements(array $requirements, string $level): array { $result = []; if (!empty($requirements['PHP'])) { $versionRequirement = new ComparisonRequirement( $requirements['PHP']['version'], new VersionComparisonOperator(empty($requirements['PHP']['operator']) ? '>=' : $requirements['PHP']['operator']), ); if ($level === 'class') { $result[] = Metadata::requiresPhpOnClass($versionRequirement); } else { $result[] = Metadata::requiresPhpOnMethod($versionRequirement); } } elseif (!empty($requirements['PHP_constraint'])) { $versionRequirement = new ConstraintRequirement($requirements['PHP_constraint']['constraint']); if ($level === 'class') { $result[] = Metadata::requiresPhpOnClass($versionRequirement); } else { $result[] = Metadata::requiresPhpOnMethod($versionRequirement); } } if (!empty($requirements['extensions'])) { foreach ($requirements['extensions'] as $extension) { if (isset($requirements['extension_versions'][$extension])) { continue; } if ($level === 'class') { $result[] = Metadata::requiresPhpExtensionOnClass($extension, null); } else { $result[] = Metadata::requiresPhpExtensionOnMethod($extension, null); } } } if (!empty($requirements['extension_versions'])) { foreach ($requirements['extension_versions'] as $extension => $version) { $versionRequirement = new ComparisonRequirement( $version['version'], new VersionComparisonOperator(empty($version['operator']) ? '>=' : $version['operator']), ); if ($level === 'class') { $result[] = Metadata::requiresPhpExtensionOnClass($extension, $versionRequirement); } else { $result[] = Metadata::requiresPhpExtensionOnMethod($extension, $versionRequirement); } } } if (!empty($requirements['PHPUnit'])) { $versionRequirement = new ComparisonRequirement( $requirements['PHPUnit']['version'], new VersionComparisonOperator(empty($requirements['PHPUnit']['operator']) ? '>=' : $requirements['PHPUnit']['operator']), ); if ($level === 'class') { $result[] = Metadata::requiresPhpunitOnClass($versionRequirement); } else { $result[] = Metadata::requiresPhpunitOnMethod($versionRequirement); } } elseif (!empty($requirements['PHPUnit_constraint'])) { $versionRequirement = new ConstraintRequirement($requirements['PHPUnit_constraint']['constraint']); if ($level === 'class') { $result[] = Metadata::requiresPhpunitOnClass($versionRequirement); } else { $result[] = Metadata::requiresPhpunitOnMethod($versionRequirement); } } if (!empty($requirements['OSFAMILY'])) { if ($level === 'class') { $result[] = Metadata::requiresOperatingSystemFamilyOnClass($requirements['OSFAMILY']); } else { $result[] = Metadata::requiresOperatingSystemFamilyOnMethod($requirements['OSFAMILY']); } } if (!empty($requirements['OS'])) { if ($level === 'class') { $result[] = Metadata::requiresOperatingSystemOnClass($requirements['OS']); } else { $result[] = Metadata::requiresOperatingSystemOnMethod($requirements['OS']); } } if (!empty($requirements['functions'])) { foreach ($requirements['functions'] as $function) { $pieces = explode('::', $function); if (count($pieces) === 2) { if ($level === 'class') { $result[] = Metadata::requiresMethodOnClass($pieces[0], $pieces[1]); } else { $result[] = Metadata::requiresMethodOnMethod($pieces[0], $pieces[1]); } } elseif ($level === 'class') { $result[] = Metadata::requiresFunctionOnClass($function); } else { $result[] = Metadata::requiresFunctionOnMethod($function); } } } if (!empty($requirements['setting'])) { foreach ($requirements['setting'] as $setting => $value) { if ($level === 'class') { $result[] = Metadata::requiresSettingOnClass($setting, $value); } else { $result[] = Metadata::requiresSettingOnMethod($setting, $value); } } } return $result; } } Parser/Registry.php 0000644 00000001735 15111216107 0010322 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata\Parser; /** * Attribute and annotation information is static within a single PHP process. * It is therefore okay to use a Singleton registry here. * * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class Registry { private static ?Parser $instance = null; public static function parser(): Parser { return self::$instance ?? self::$instance = self::build(); } private function __construct() { } private static function build(): Parser { return new CachingParser( new ParserChain( new AttributeParser, new AnnotationParser, ), ); } } Parser/ParserChain.php 0000644 00000003556 15111216107 0010714 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata\Parser; use PHPUnit\Metadata\MetadataCollection; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class ParserChain implements Parser { private readonly Parser $attributeReader; private readonly Parser $annotationReader; public function __construct(Parser $attributeReader, Parser $annotationReader) { $this->attributeReader = $attributeReader; $this->annotationReader = $annotationReader; } /** * @psalm-param class-string $className */ public function forClass(string $className): MetadataCollection { $metadata = $this->attributeReader->forClass($className); if (!$metadata->isEmpty()) { return $metadata; } return $this->annotationReader->forClass($className); } /** * @psalm-param class-string $className * @psalm-param non-empty-string $methodName */ public function forMethod(string $className, string $methodName): MetadataCollection { $metadata = $this->attributeReader->forMethod($className, $methodName); if (!$metadata->isEmpty()) { return $metadata; } return $this->annotationReader->forMethod($className, $methodName); } /** * @psalm-param class-string $className * @psalm-param non-empty-string $methodName */ public function forClassAndMethod(string $className, string $methodName): MetadataCollection { return $this->forClass($className)->mergeWith( $this->forMethod($className, $methodName), ); } } CoversFunction.php 0000644 00000002470 15111216107 0010222 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class CoversFunction extends Metadata { /** * @psalm-var non-empty-string */ private readonly string $functionName; /** * @psalm-param 0|1 $level * @psalm-param non-empty-string $functionName */ protected function __construct(int $level, string $functionName) { parent::__construct($level); $this->functionName = $functionName; } /** * @psalm-assert-if-true CoversFunction $this */ public function isCoversFunction(): bool { return true; } /** * @psalm-return non-empty-string */ public function functionName(): string { return $this->functionName; } /** * @internal This method is not covered by the backward compatibility promise for PHPUnit */ public function asStringForCodeUnitMapper(): string { return '::' . $this->functionName; } } RequiresPhp.php 0000644 00000002023 15111216107 0007514 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; use PHPUnit\Metadata\Version\Requirement; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class RequiresPhp extends Metadata { private readonly Requirement $versionRequirement; /** * @psalm-param 0|1 $level */ protected function __construct(int $level, Requirement $versionRequirement) { parent::__construct($level); $this->versionRequirement = $versionRequirement; } /** * @psalm-assert-if-true RequiresPhp $this */ public function isRequiresPhp(): bool { return true; } public function versionRequirement(): Requirement { return $this->versionRequirement; } } Version/ConstraintRequirement.php 0000644 00000002453 15111216107 0013246 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata\Version; use function preg_replace; use PharIo\Version\Version; use PharIo\Version\VersionConstraint; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class ConstraintRequirement extends Requirement { private readonly VersionConstraint $constraint; public function __construct(VersionConstraint $constraint) { $this->constraint = $constraint; } /** * @psalm-suppress ImpureMethodCall */ public function isSatisfiedBy(string $version): bool { return $this->constraint->complies( new Version($this->sanitize($version)), ); } /** * @psalm-suppress ImpureMethodCall */ public function asString(): string { return $this->constraint->asString(); } private function sanitize(string $version): string { return preg_replace( '/^(\d+\.\d+(?:.\d+)?).*$/', '$1', $version, ); } } Version/ComparisonRequirement.php 0000644 00000002117 15111216107 0013231 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata\Version; use function version_compare; use PHPUnit\Util\VersionComparisonOperator; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class ComparisonRequirement extends Requirement { private readonly string $version; private readonly VersionComparisonOperator $operator; public function __construct(string $version, VersionComparisonOperator $operator) { $this->version = $version; $this->operator = $operator; } public function isSatisfiedBy(string $version): bool { return version_compare($version, $this->version, $this->operator->asString()); } public function asString(): string { return $this->operator->asString() . ' ' . $this->version; } } Version/Requirement.php 0000644 00000003504 15111216107 0011177 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata\Version; use function preg_match; use PharIo\Version\UnsupportedVersionConstraintException; use PharIo\Version\VersionConstraintParser; use PHPUnit\Metadata\InvalidVersionRequirementException; use PHPUnit\Util\InvalidVersionOperatorException; use PHPUnit\Util\VersionComparisonOperator; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ abstract class Requirement { private const VERSION_COMPARISON = '/(?P<operator>[<>=!]{0,2})\s*(?P<version>[\d\.-]+(dev|(RC|alpha|beta)[\d\.])?)[ \t]*\r?$/m'; /** * @throws InvalidVersionOperatorException * @throws InvalidVersionRequirementException */ public static function from(string $versionRequirement): self { try { return new ConstraintRequirement( (new VersionConstraintParser)->parse( $versionRequirement, ), ); } catch (UnsupportedVersionConstraintException) { if (preg_match(self::VERSION_COMPARISON, $versionRequirement, $matches)) { return new ComparisonRequirement( $matches['version'], new VersionComparisonOperator( !empty($matches['operator']) ? $matches['operator'] : '>=', ), ); } } throw new InvalidVersionRequirementException; } abstract public function isSatisfiedBy(string $version): bool; abstract public function asString(): string; } Exception/NoVersionRequirementException.php 0000644 00000000615 15111216107 0015232 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; use RuntimeException; final class NoVersionRequirementException extends RuntimeException implements Exception { } Exception/Exception.php 0000644 00000000515 15111216107 0011145 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; interface Exception extends \PHPUnit\Exception { } Exception/AnnotationsAreNotSupportedForInternalClassesException.php 0000644 00000001577 15111216107 0022075 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; use function sprintf; use RuntimeException; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class AnnotationsAreNotSupportedForInternalClassesException extends RuntimeException implements \PHPUnit\Exception { /** * @psalm-param class-string $className */ public function __construct(string $className) { parent::__construct( sprintf( 'Annotations can only be parsed for user-defined classes, trying to parse annotations for class "%s"', $className, ), ); } } Exception/ReflectionException.php 0000644 00000000755 15111216107 0013166 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; use RuntimeException; /** * @internal This class is not covered by the backward compatibility promise for PHPUnit */ final class ReflectionException extends RuntimeException implements \PHPUnit\Exception { } Exception/InvalidVersionRequirementException.php 0000644 00000000622 15111216107 0016242 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; use RuntimeException; final class InvalidVersionRequirementException extends RuntimeException implements Exception { } TestDox.php 0000644 00000002015 15111216107 0006640 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class TestDox extends Metadata { /** * @psalm-var non-empty-string */ private readonly string $text; /** * @psalm-param 0|1 $level * @psalm-param non-empty-string $text */ protected function __construct(int $level, string $text) { parent::__construct($level); $this->text = $text; } /** * @psalm-assert-if-true TestDox $this */ public function isTestDox(): bool { return true; } /** * @psalm-return non-empty-string */ public function text(): string { return $this->text; } } AfterClass.php 0000644 00000001126 15111216110 0007271 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class AfterClass extends Metadata { /** * @psalm-assert-if-true AfterClass $this */ public function isAfterClass(): bool { return true; } } BackupStaticProperties.php 0000644 00000001662 15111216110 0011701 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class BackupStaticProperties extends Metadata { private readonly bool $enabled; /** * @psalm-param 0|1 $level */ protected function __construct(int $level, bool $enabled) { parent::__construct($level); $this->enabled = $enabled; } /** * @psalm-assert-if-true BackupStaticProperties $this */ public function isBackupStaticProperties(): bool { return true; } public function enabled(): bool { return $this->enabled; } } CoversNothing.php 0000644 00000001137 15111216110 0010034 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class CoversNothing extends Metadata { /** * @psalm-assert-if-true CoversNothing $this */ public function isCoversNothing(): bool { return true; } } UsesClass.php 0000644 00000002447 15111216110 0007156 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class UsesClass extends Metadata { /** * @psalm-var class-string */ private readonly string $className; /** * @psalm-param 0|1 $level * @psalm-param class-string $className */ protected function __construct(int $level, string $className) { parent::__construct($level); $this->className = $className; } /** * @psalm-assert-if-true UsesClass $this */ public function isUsesClass(): bool { return true; } /** * @psalm-return class-string */ public function className(): string { return $this->className; } /** * @psalm-return class-string * * @internal This method is not covered by the backward compatibility promise for PHPUnit */ public function asStringForCodeUnitMapper(): string { return $this->className; } } ExcludeStaticPropertyFromBackup.php 0000644 00000002726 15111216110 0013531 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class ExcludeStaticPropertyFromBackup extends Metadata { /** * @psalm-var class-string */ private readonly string $className; /** * @psalm-var non-empty-string */ private readonly string $propertyName; /** * @psalm-param 0|1 $level * @psalm-param class-string $className * @psalm-param non-empty-string $propertyName */ protected function __construct(int $level, string $className, string $propertyName) { parent::__construct($level); $this->className = $className; $this->propertyName = $propertyName; } /** * @psalm-assert-if-true ExcludeStaticPropertyFromBackup $this */ public function isExcludeStaticPropertyFromBackup(): bool { return true; } /** * @psalm-return class-string */ public function className(): string { return $this->className; } /** * @psalm-return non-empty-string */ public function propertyName(): string { return $this->propertyName; } } WithoutErrorHandler.php 0000644 00000001161 15111216110 0011214 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class WithoutErrorHandler extends Metadata { /** * @psalm-assert-if-true WithoutErrorHandler $this */ public function isWithoutErrorHandler(): bool { return true; } } RequiresPhpExtension.php 0000644 00000003370 15111216110 0011411 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; use PHPUnit\Metadata\Version\Requirement; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class RequiresPhpExtension extends Metadata { /** * @psalm-var non-empty-string */ private readonly string $extension; private readonly ?Requirement $versionRequirement; /** * @psalm-param 0|1 $level * @psalm-param non-empty-string $extension */ protected function __construct(int $level, string $extension, ?Requirement $versionRequirement) { parent::__construct($level); $this->extension = $extension; $this->versionRequirement = $versionRequirement; } /** * @psalm-assert-if-true RequiresPhpExtension $this */ public function isRequiresPhpExtension(): bool { return true; } /** * @psalm-return non-empty-string */ public function extension(): string { return $this->extension; } /** * @psalm-assert-if-true !null $this->versionRequirement */ public function hasVersionRequirement(): bool { return $this->versionRequirement !== null; } /** * @throws NoVersionRequirementException */ public function versionRequirement(): Requirement { if ($this->versionRequirement === null) { throw new NoVersionRequirementException; } return $this->versionRequirement; } } RequiresOperatingSystem.php 0000644 00000002207 15111216110 0012120 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class RequiresOperatingSystem extends Metadata { /** * @psalm-var non-empty-string */ private readonly string $operatingSystem; /** * @psalm-param 0|1 $level * @psalm-param non-empty-string $operatingSystem */ public function __construct(int $level, string $operatingSystem) { parent::__construct($level); $this->operatingSystem = $operatingSystem; } /** * @psalm-assert-if-true RequiresOperatingSystem $this */ public function isRequiresOperatingSystem(): bool { return true; } /** * @psalm-return non-empty-string */ public function operatingSystem(): string { return $this->operatingSystem; } } UsesDefaultClass.php 0000644 00000002077 15111216110 0010462 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class UsesDefaultClass extends Metadata { /** * @psalm-var class-string */ private readonly string $className; /** * @psalm-param 0|1 $level * @psalm-param class-string $className */ protected function __construct(int $level, string $className) { parent::__construct($level); $this->className = $className; } /** * @psalm-assert-if-true UsesDefaultClass $this */ public function isUsesDefaultClass(): bool { return true; } /** * @psalm-return class-string */ public function className(): string { return $this->className; } } DoesNotPerformAssertions.php 0000644 00000001200 15111216110 0012214 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class DoesNotPerformAssertions extends Metadata { /** * @psalm-assert-if-true DoesNotPerformAssertions $this */ public function isDoesNotPerformAssertions(): bool { return true; } } Test.php 0000644 00000001104 15111216110 0006155 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class Test extends Metadata { /** * @psalm-assert-if-true Test $this */ public function isTest(): bool { return true; } } Uses.php 0000644 00000002022 15111216110 0006155 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class Uses extends Metadata { /** * @psalm-var non-empty-string */ private readonly string $target; /** * @psalm-param 0|1 $level * @psalm-param non-empty-string $target */ protected function __construct(int $level, string $target) { parent::__construct($level); $this->target = $target; } /** * @psalm-assert-if-true Uses $this */ public function isUses(): bool { return true; } /** * @psalm-return non-empty-string */ public function target(): string { return $this->target; } } RequiresPhpunit.php 0000644 00000002037 15111216111 0010414 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; use PHPUnit\Metadata\Version\Requirement; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class RequiresPhpunit extends Metadata { private readonly Requirement $versionRequirement; /** * @psalm-param 0|1 $level */ protected function __construct(int $level, Requirement $versionRequirement) { parent::__construct($level); $this->versionRequirement = $versionRequirement; } /** * @psalm-assert-if-true RequiresPhpunit $this */ public function isRequiresPhpunit(): bool { return true; } public function versionRequirement(): Requirement { return $this->versionRequirement; } } DataProvider.php 0000644 00000002615 15111216111 0007633 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class DataProvider extends Metadata { /** * @psalm-var class-string */ private readonly string $className; /** * @psalm-var non-empty-string */ private readonly string $methodName; /** * @psalm-param 0|1 $level * @psalm-param class-string $className * @psalm-param non-empty-string $methodName */ protected function __construct(int $level, string $className, string $methodName) { parent::__construct($level); $this->className = $className; $this->methodName = $methodName; } /** * @psalm-assert-if-true DataProvider $this */ public function isDataProvider(): bool { return true; } /** * @psalm-return class-string */ public function className(): string { return $this->className; } /** * @psalm-return non-empty-string */ public function methodName(): string { return $this->methodName; } } BeforeClass.php 0000644 00000001131 15111216111 0007427 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class BeforeClass extends Metadata { /** * @psalm-assert-if-true BeforeClass $this */ public function isBeforeClass(): bool { return true; } } UsesFunction.php 0000644 00000002457 15111216111 0007700 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class UsesFunction extends Metadata { /** * @psalm-var non-empty-string */ private readonly string $functionName; /** * @psalm-param 0|1 $level * @psalm-param non-empty-string $functionName */ public function __construct(int $level, string $functionName) { parent::__construct($level); $this->functionName = $functionName; } /** * @psalm-assert-if-true UsesFunction $this */ public function isUsesFunction(): bool { return true; } /** * @psalm-return non-empty-string */ public function functionName(): string { return $this->functionName; } /** * @internal This method is not covered by the backward compatibility promise for PHPUnit */ public function asStringForCodeUnitMapper(): string { return '::' . $this->functionName; } } Covers.php 0000644 00000002030 15111216111 0006477 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class Covers extends Metadata { /** * @psalm-var non-empty-string */ private readonly string $target; /** * @psalm-param 0|1 $level * @psalm-param non-empty-string $target */ protected function __construct(int $level, string $target) { parent::__construct($level); $this->target = $target; } /** * @psalm-assert-if-true Covers $this */ public function isCovers(): bool { return true; } /** * @psalm-return non-empty-string */ public function target(): string { return $this->target; } } PostCondition.php 0000644 00000001137 15111216111 0010041 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class PostCondition extends Metadata { /** * @psalm-assert-if-true PostCondition $this */ public function isPostCondition(): bool { return true; } } PreserveGlobalState.php 0000644 00000001651 15111216111 0011163 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class PreserveGlobalState extends Metadata { private readonly bool $enabled; /** * @psalm-param 0|1 $level */ protected function __construct(int $level, bool $enabled) { parent::__construct($level); $this->enabled = $enabled; } /** * @psalm-assert-if-true PreserveGlobalState $this */ public function isPreserveGlobalState(): bool { return true; } public function enabled(): bool { return $this->enabled; } } Group.php 0000644 00000002052 15111216111 0006336 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class Group extends Metadata { /** * @psalm-var non-empty-string */ private readonly string $groupName; /** * @psalm-param 0|1 $level * @psalm-param non-empty-string $groupName */ protected function __construct(int $level, string $groupName) { parent::__construct($level); $this->groupName = $groupName; } /** * @psalm-assert-if-true Group $this */ public function isGroup(): bool { return true; } /** * @psalm-return non-empty-string */ public function groupName(): string { return $this->groupName; } } CoversDefaultClass.php 0000644 00000002105 15111216111 0010775 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class CoversDefaultClass extends Metadata { /** * @psalm-var class-string */ private readonly string $className; /** * @psalm-param 0|1 $level * @psalm-param class-string $className */ protected function __construct(int $level, string $className) { parent::__construct($level); $this->className = $className; } /** * @psalm-assert-if-true CoversDefaultClass $this */ public function isCoversDefaultClass(): bool { return true; } /** * @psalm-return class-string */ public function className(): string { return $this->className; } } RunClassInSeparateProcess.php 0000644 00000001203 15111216111 0012304 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class RunClassInSeparateProcess extends Metadata { /** * @psalm-assert-if-true RunClassInSeparateProcess $this */ public function isRunClassInSeparateProcess(): bool { return true; } } DependsOnClass.php 0000644 00000002665 15111216111 0010121 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class DependsOnClass extends Metadata { /** * @psalm-var class-string */ private readonly string $className; private readonly bool $deepClone; private readonly bool $shallowClone; /** * @psalm-param 0|1 $level * @psalm-param class-string $className */ protected function __construct(int $level, string $className, bool $deepClone, bool $shallowClone) { parent::__construct($level); $this->className = $className; $this->deepClone = $deepClone; $this->shallowClone = $shallowClone; } /** * @psalm-assert-if-true DependsOnClass $this */ public function isDependsOnClass(): bool { return true; } /** * @psalm-return class-string */ public function className(): string { return $this->className; } public function deepClone(): bool { return $this->deepClone; } public function shallowClone(): bool { return $this->shallowClone; } } RunTestsInSeparateProcesses.php 0000644 00000001211 15111216111 0012670 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class RunTestsInSeparateProcesses extends Metadata { /** * @psalm-assert-if-true RunTestsInSeparateProcesses $this */ public function isRunTestsInSeparateProcesses(): bool { return true; } } RequiresSetting.php 0000644 00000002562 15111216111 0010405 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class RequiresSetting extends Metadata { /** * @psalm-var non-empty-string */ private readonly string $setting; /** * @psalm-var non-empty-string */ private readonly string $value; /** * @psalm-param 0|1 $level * @psalm-param non-empty-string $setting * @psalm-param non-empty-string $value */ protected function __construct(int $level, string $setting, string $value) { parent::__construct($level); $this->setting = $setting; $this->value = $value; } /** * @psalm-assert-if-true RequiresSetting $this */ public function isRequiresSetting(): bool { return true; } /** * @psalm-return non-empty-string */ public function setting(): string { return $this->setting; } /** * @psalm-return non-empty-string */ public function value(): string { return $this->value; } } RunInSeparateProcess.php 0000644 00000001164 15111216111 0011324 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class RunInSeparateProcess extends Metadata { /** * @psalm-assert-if-true RunInSeparateProcess $this */ public function isRunInSeparateProcess(): bool { return true; } } TestWith.php 0000644 00000001571 15111216111 0007022 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class TestWith extends Metadata { private readonly array $data; /** * @psalm-param 0|1 $level */ protected function __construct(int $level, array $data) { parent::__construct($level); $this->data = $data; } /** * @psalm-assert-if-true TestWith $this */ public function isTestWith(): bool { return true; } public function data(): array { return $this->data; } } Before.php 0000644 00000001112 15111216111 0006440 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class Before extends Metadata { /** * @psalm-assert-if-true Before $this */ public function isBefore(): bool { return true; } } Metadata.php 0000644 00000050416 15111216111 0006771 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; use PHPUnit\Metadata\Version\Requirement; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ abstract class Metadata { private const CLASS_LEVEL = 0; private const METHOD_LEVEL = 1; /** * @psalm-var 0|1 */ private readonly int $level; public static function after(): After { return new After(self::METHOD_LEVEL); } public static function afterClass(): AfterClass { return new AfterClass(self::METHOD_LEVEL); } public static function backupGlobalsOnClass(bool $enabled): BackupGlobals { return new BackupGlobals(self::CLASS_LEVEL, $enabled); } public static function backupGlobalsOnMethod(bool $enabled): BackupGlobals { return new BackupGlobals(self::METHOD_LEVEL, $enabled); } public static function backupStaticPropertiesOnClass(bool $enabled): BackupStaticProperties { return new BackupStaticProperties(self::CLASS_LEVEL, $enabled); } public static function backupStaticPropertiesOnMethod(bool $enabled): BackupStaticProperties { return new BackupStaticProperties(self::METHOD_LEVEL, $enabled); } public static function before(): Before { return new Before(self::METHOD_LEVEL); } public static function beforeClass(): BeforeClass { return new BeforeClass(self::METHOD_LEVEL); } /** * @psalm-param class-string $className */ public static function coversClass(string $className): CoversClass { return new CoversClass(self::CLASS_LEVEL, $className); } /** * @psalm-param non-empty-string $functionName */ public static function coversFunction(string $functionName): CoversFunction { return new CoversFunction(self::CLASS_LEVEL, $functionName); } /** * @psalm-param non-empty-string $target */ public static function coversOnClass(string $target): Covers { return new Covers(self::CLASS_LEVEL, $target); } /** * @psalm-param non-empty-string $target */ public static function coversOnMethod(string $target): Covers { return new Covers(self::METHOD_LEVEL, $target); } /** * @psalm-param class-string $className */ public static function coversDefaultClass(string $className): CoversDefaultClass { return new CoversDefaultClass(self::CLASS_LEVEL, $className); } public static function coversNothingOnClass(): CoversNothing { return new CoversNothing(self::CLASS_LEVEL); } public static function coversNothingOnMethod(): CoversNothing { return new CoversNothing(self::METHOD_LEVEL); } /** * @psalm-param class-string $className * @psalm-param non-empty-string $methodName */ public static function dataProvider(string $className, string $methodName): DataProvider { return new DataProvider(self::METHOD_LEVEL, $className, $methodName); } /** * @psalm-param class-string $className */ public static function dependsOnClass(string $className, bool $deepClone, bool $shallowClone): DependsOnClass { return new DependsOnClass(self::METHOD_LEVEL, $className, $deepClone, $shallowClone); } /** * @psalm-param class-string $className * @psalm-param non-empty-string $methodName */ public static function dependsOnMethod(string $className, string $methodName, bool $deepClone, bool $shallowClone): DependsOnMethod { return new DependsOnMethod(self::METHOD_LEVEL, $className, $methodName, $deepClone, $shallowClone); } public static function doesNotPerformAssertionsOnClass(): DoesNotPerformAssertions { return new DoesNotPerformAssertions(self::CLASS_LEVEL); } public static function doesNotPerformAssertionsOnMethod(): DoesNotPerformAssertions { return new DoesNotPerformAssertions(self::METHOD_LEVEL); } /** * @psalm-param non-empty-string $globalVariableName */ public static function excludeGlobalVariableFromBackupOnClass(string $globalVariableName): ExcludeGlobalVariableFromBackup { return new ExcludeGlobalVariableFromBackup(self::CLASS_LEVEL, $globalVariableName); } /** * @psalm-param non-empty-string $globalVariableName */ public static function excludeGlobalVariableFromBackupOnMethod(string $globalVariableName): ExcludeGlobalVariableFromBackup { return new ExcludeGlobalVariableFromBackup(self::METHOD_LEVEL, $globalVariableName); } /** * @psalm-param class-string $className * @psalm-param non-empty-string $propertyName */ public static function excludeStaticPropertyFromBackupOnClass(string $className, string $propertyName): ExcludeStaticPropertyFromBackup { return new ExcludeStaticPropertyFromBackup(self::CLASS_LEVEL, $className, $propertyName); } /** * @psalm-param class-string $className * @psalm-param non-empty-string $propertyName */ public static function excludeStaticPropertyFromBackupOnMethod(string $className, string $propertyName): ExcludeStaticPropertyFromBackup { return new ExcludeStaticPropertyFromBackup(self::METHOD_LEVEL, $className, $propertyName); } /** * @psalm-param non-empty-string $groupName */ public static function groupOnClass(string $groupName): Group { return new Group(self::CLASS_LEVEL, $groupName); } /** * @psalm-param non-empty-string $groupName */ public static function groupOnMethod(string $groupName): Group { return new Group(self::METHOD_LEVEL, $groupName); } /** * @psalm-param class-string $className */ public static function ignoreClassForCodeCoverage(string $className): IgnoreClassForCodeCoverage { return new IgnoreClassForCodeCoverage(self::CLASS_LEVEL, $className); } /** * @psalm-param class-string $className * @psalm-param non-empty-string $methodName */ public static function ignoreMethodForCodeCoverage(string $className, string $methodName): IgnoreMethodForCodeCoverage { return new IgnoreMethodForCodeCoverage(self::CLASS_LEVEL, $className, $methodName); } /** * @psalm-param non-empty-string $functionName */ public static function ignoreFunctionForCodeCoverage(string $functionName): IgnoreFunctionForCodeCoverage { return new IgnoreFunctionForCodeCoverage(self::CLASS_LEVEL, $functionName); } public static function postCondition(): PostCondition { return new PostCondition(self::METHOD_LEVEL); } public static function preCondition(): PreCondition { return new PreCondition(self::METHOD_LEVEL); } public static function preserveGlobalStateOnClass(bool $enabled): PreserveGlobalState { return new PreserveGlobalState(self::CLASS_LEVEL, $enabled); } public static function preserveGlobalStateOnMethod(bool $enabled): PreserveGlobalState { return new PreserveGlobalState(self::METHOD_LEVEL, $enabled); } /** * @psalm-param non-empty-string $functionName */ public static function requiresFunctionOnClass(string $functionName): RequiresFunction { return new RequiresFunction(self::CLASS_LEVEL, $functionName); } /** * @psalm-param non-empty-string $functionName */ public static function requiresFunctionOnMethod(string $functionName): RequiresFunction { return new RequiresFunction(self::METHOD_LEVEL, $functionName); } /** * @psalm-param class-string $className * @psalm-param non-empty-string $methodName */ public static function requiresMethodOnClass(string $className, string $methodName): RequiresMethod { return new RequiresMethod(self::CLASS_LEVEL, $className, $methodName); } /** * @psalm-param class-string $className * @psalm-param non-empty-string $methodName */ public static function requiresMethodOnMethod(string $className, string $methodName): RequiresMethod { return new RequiresMethod(self::METHOD_LEVEL, $className, $methodName); } /** * @psalm-param non-empty-string $operatingSystem */ public static function requiresOperatingSystemOnClass(string $operatingSystem): RequiresOperatingSystem { return new RequiresOperatingSystem(self::CLASS_LEVEL, $operatingSystem); } /** * @psalm-param non-empty-string $operatingSystem */ public static function requiresOperatingSystemOnMethod(string $operatingSystem): RequiresOperatingSystem { return new RequiresOperatingSystem(self::METHOD_LEVEL, $operatingSystem); } /** * @psalm-param non-empty-string $operatingSystemFamily */ public static function requiresOperatingSystemFamilyOnClass(string $operatingSystemFamily): RequiresOperatingSystemFamily { return new RequiresOperatingSystemFamily(self::CLASS_LEVEL, $operatingSystemFamily); } /** * @psalm-param non-empty-string $operatingSystemFamily */ public static function requiresOperatingSystemFamilyOnMethod(string $operatingSystemFamily): RequiresOperatingSystemFamily { return new RequiresOperatingSystemFamily(self::METHOD_LEVEL, $operatingSystemFamily); } public static function requiresPhpOnClass(Requirement $versionRequirement): RequiresPhp { return new RequiresPhp(self::CLASS_LEVEL, $versionRequirement); } public static function requiresPhpOnMethod(Requirement $versionRequirement): RequiresPhp { return new RequiresPhp(self::METHOD_LEVEL, $versionRequirement); } /** * @psalm-param non-empty-string $extension */ public static function requiresPhpExtensionOnClass(string $extension, ?Requirement $versionRequirement): RequiresPhpExtension { return new RequiresPhpExtension(self::CLASS_LEVEL, $extension, $versionRequirement); } /** * @psalm-param non-empty-string $extension */ public static function requiresPhpExtensionOnMethod(string $extension, ?Requirement $versionRequirement): RequiresPhpExtension { return new RequiresPhpExtension(self::METHOD_LEVEL, $extension, $versionRequirement); } public static function requiresPhpunitOnClass(Requirement $versionRequirement): RequiresPhpunit { return new RequiresPhpunit(self::CLASS_LEVEL, $versionRequirement); } public static function requiresPhpunitOnMethod(Requirement $versionRequirement): RequiresPhpunit { return new RequiresPhpunit(self::METHOD_LEVEL, $versionRequirement); } /** * @psalm-param non-empty-string $setting * @psalm-param non-empty-string $value */ public static function requiresSettingOnClass(string $setting, string $value): RequiresSetting { return new RequiresSetting(self::CLASS_LEVEL, $setting, $value); } /** * @psalm-param non-empty-string $setting * @psalm-param non-empty-string $value */ public static function requiresSettingOnMethod(string $setting, string $value): RequiresSetting { return new RequiresSetting(self::METHOD_LEVEL, $setting, $value); } public static function runClassInSeparateProcess(): RunClassInSeparateProcess { return new RunClassInSeparateProcess(self::CLASS_LEVEL); } public static function runTestsInSeparateProcesses(): RunTestsInSeparateProcesses { return new RunTestsInSeparateProcesses(self::CLASS_LEVEL); } public static function runInSeparateProcess(): RunInSeparateProcess { return new RunInSeparateProcess(self::METHOD_LEVEL); } public static function test(): Test { return new Test(self::METHOD_LEVEL); } /** * @psalm-param non-empty-string $text */ public static function testDoxOnClass(string $text): TestDox { return new TestDox(self::CLASS_LEVEL, $text); } /** * @psalm-param non-empty-string $text */ public static function testDoxOnMethod(string $text): TestDox { return new TestDox(self::METHOD_LEVEL, $text); } public static function testWith(array $data): TestWith { return new TestWith(self::METHOD_LEVEL, $data); } /** * @psalm-param class-string $className */ public static function usesClass(string $className): UsesClass { return new UsesClass(self::CLASS_LEVEL, $className); } /** * @psalm-param non-empty-string $functionName */ public static function usesFunction(string $functionName): UsesFunction { return new UsesFunction(self::CLASS_LEVEL, $functionName); } /** * @psalm-param non-empty-string $target */ public static function usesOnClass(string $target): Uses { return new Uses(self::CLASS_LEVEL, $target); } /** * @psalm-param non-empty-string $target */ public static function usesOnMethod(string $target): Uses { return new Uses(self::METHOD_LEVEL, $target); } /** * @psalm-param class-string $className */ public static function usesDefaultClass(string $className): UsesDefaultClass { return new UsesDefaultClass(self::CLASS_LEVEL, $className); } public static function withoutErrorHandler(): WithoutErrorHandler { return new WithoutErrorHandler(self::METHOD_LEVEL); } /** * @psalm-param 0|1 $level */ protected function __construct(int $level) { $this->level = $level; } public function isClassLevel(): bool { return $this->level === self::CLASS_LEVEL; } public function isMethodLevel(): bool { return $this->level === self::METHOD_LEVEL; } /** * @psalm-assert-if-true After $this */ public function isAfter(): bool { return false; } /** * @psalm-assert-if-true AfterClass $this */ public function isAfterClass(): bool { return false; } /** * @psalm-assert-if-true BackupGlobals $this */ public function isBackupGlobals(): bool { return false; } /** * @psalm-assert-if-true BackupStaticProperties $this */ public function isBackupStaticProperties(): bool { return false; } /** * @psalm-assert-if-true BeforeClass $this */ public function isBeforeClass(): bool { return false; } /** * @psalm-assert-if-true Before $this */ public function isBefore(): bool { return false; } /** * @psalm-assert-if-true Covers $this */ public function isCovers(): bool { return false; } /** * @psalm-assert-if-true CoversClass $this */ public function isCoversClass(): bool { return false; } /** * @psalm-assert-if-true CoversDefaultClass $this */ public function isCoversDefaultClass(): bool { return false; } /** * @psalm-assert-if-true CoversFunction $this */ public function isCoversFunction(): bool { return false; } /** * @psalm-assert-if-true CoversNothing $this */ public function isCoversNothing(): bool { return false; } /** * @psalm-assert-if-true DataProvider $this */ public function isDataProvider(): bool { return false; } /** * @psalm-assert-if-true DependsOnClass $this */ public function isDependsOnClass(): bool { return false; } /** * @psalm-assert-if-true DependsOnMethod $this */ public function isDependsOnMethod(): bool { return false; } /** * @psalm-assert-if-true DoesNotPerformAssertions $this */ public function isDoesNotPerformAssertions(): bool { return false; } /** * @psalm-assert-if-true ExcludeGlobalVariableFromBackup $this */ public function isExcludeGlobalVariableFromBackup(): bool { return false; } /** * @psalm-assert-if-true ExcludeStaticPropertyFromBackup $this */ public function isExcludeStaticPropertyFromBackup(): bool { return false; } /** * @psalm-assert-if-true Group $this */ public function isGroup(): bool { return false; } /** * @psalm-assert-if-true IgnoreClassForCodeCoverage $this */ public function isIgnoreClassForCodeCoverage(): bool { return false; } /** * @psalm-assert-if-true IgnoreMethodForCodeCoverage $this */ public function isIgnoreMethodForCodeCoverage(): bool { return false; } /** * @psalm-assert-if-true IgnoreFunctionForCodeCoverage $this */ public function isIgnoreFunctionForCodeCoverage(): bool { return false; } /** * @psalm-assert-if-true RunClassInSeparateProcess $this */ public function isRunClassInSeparateProcess(): bool { return false; } /** * @psalm-assert-if-true RunInSeparateProcess $this */ public function isRunInSeparateProcess(): bool { return false; } /** * @psalm-assert-if-true RunTestsInSeparateProcesses $this */ public function isRunTestsInSeparateProcesses(): bool { return false; } /** * @psalm-assert-if-true Test $this */ public function isTest(): bool { return false; } /** * @psalm-assert-if-true PreCondition $this */ public function isPreCondition(): bool { return false; } /** * @psalm-assert-if-true PostCondition $this */ public function isPostCondition(): bool { return false; } /** * @psalm-assert-if-true PreserveGlobalState $this */ public function isPreserveGlobalState(): bool { return false; } /** * @psalm-assert-if-true RequiresMethod $this */ public function isRequiresMethod(): bool { return false; } /** * @psalm-assert-if-true RequiresFunction $this */ public function isRequiresFunction(): bool { return false; } /** * @psalm-assert-if-true RequiresOperatingSystem $this */ public function isRequiresOperatingSystem(): bool { return false; } /** * @psalm-assert-if-true RequiresOperatingSystemFamily $this */ public function isRequiresOperatingSystemFamily(): bool { return false; } /** * @psalm-assert-if-true RequiresPhp $this */ public function isRequiresPhp(): bool { return false; } /** * @psalm-assert-if-true RequiresPhpExtension $this */ public function isRequiresPhpExtension(): bool { return false; } /** * @psalm-assert-if-true RequiresPhpunit $this */ public function isRequiresPhpunit(): bool { return false; } /** * @psalm-assert-if-true RequiresSetting $this */ public function isRequiresSetting(): bool { return false; } /** * @psalm-assert-if-true TestDox $this */ public function isTestDox(): bool { return false; } /** * @psalm-assert-if-true TestWith $this */ public function isTestWith(): bool { return false; } /** * @psalm-assert-if-true Uses $this */ public function isUses(): bool { return false; } /** * @psalm-assert-if-true UsesClass $this */ public function isUsesClass(): bool { return false; } /** * @psalm-assert-if-true UsesDefaultClass $this */ public function isUsesDefaultClass(): bool { return false; } /** * @psalm-assert-if-true UsesFunction $this */ public function isUsesFunction(): bool { return false; } /** * @psalm-assert-if-true WithoutErrorHandler $this */ public function isWithoutErrorHandler(): bool { return false; } } CoversClass.php 0000644 00000002455 15111216112 0007501 0 ustar 00 <?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Metadata; /** * @psalm-immutable * * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit */ final class CoversClass extends Metadata { /** * @psalm-var class-string */ private readonly string $className; /** * @psalm-param 0|1 $level * @psalm-param class-string $className */ protected function __construct(int $level, string $className) { parent::__construct($level); $this->className = $className; } /** * @psalm-assert-if-true CoversClass $this */ public function isCoversClass(): bool { return true; } /** * @psalm-return class-string */ public function className(): string { return $this->className; } /** * @psalm-return class-string * * @internal This method is not covered by the backward compatibility promise for PHPUnit */ public function asStringForCodeUnitMapper(): string { return $this->className; } }