diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 6e540218..9968c69c 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -25,7 +25,7 @@ parameters: path: src/Reflection/EnumReflectionProperty.php - - message: '#^PHPDoc tag @var with type Doctrine\\Persistence\\Mapping\\ClassMetadata\ is not subtype of native type PHPUnit\\Framework\\MockObject\\MockObject\.$#' + message: '#^PHPDoc tag @var with type Doctrine\\Persistence\\Mapping\\ClassMetadata\ is not subtype of native type PHPUnit\\Framework\\MockObject\\Stub\.$#' identifier: varTag.nativeType count: 1 path: tests/Mapping/ClassMetadataFactoryTest.php diff --git a/src/Mapping/Driver/ClassNames.php b/src/Mapping/Driver/ClassNames.php index 9014ddd9..7d1b001c 100644 --- a/src/Mapping/Driver/ClassNames.php +++ b/src/Mapping/Driver/ClassNames.php @@ -13,7 +13,7 @@ { /** @param list $classNames */ public function __construct( - private array $classNames, + private readonly array $classNames, ) { } diff --git a/src/Mapping/Driver/DefaultFileLocator.php b/src/Mapping/Driver/DefaultFileLocator.php index f8df1f1d..239fbed4 100644 --- a/src/Mapping/Driver/DefaultFileLocator.php +++ b/src/Mapping/Driver/DefaultFileLocator.php @@ -47,7 +47,6 @@ public function __construct( private string|null $fileExtension = null, ) { $this->addPaths((array) $paths); - $this->fileExtension = $fileExtension; } /** diff --git a/src/Mapping/Driver/FileClassLocator.php b/src/Mapping/Driver/FileClassLocator.php index 09d5e534..2fd525d5 100644 --- a/src/Mapping/Driver/FileClassLocator.php +++ b/src/Mapping/Driver/FileClassLocator.php @@ -39,7 +39,7 @@ { /** @param iterable $files An iterable of files to include. */ public function __construct( - private iterable $files, + private readonly iterable $files, ) { } diff --git a/src/Mapping/Driver/MappingDriverChain.php b/src/Mapping/Driver/MappingDriverChain.php index ed773443..b76a3571 100644 --- a/src/Mapping/Driver/MappingDriverChain.php +++ b/src/Mapping/Driver/MappingDriverChain.php @@ -10,7 +10,7 @@ use function array_keys; use function spl_object_id; -use function strpos; +use function str_starts_with; /** * The DriverChain allows you to add multiple other mapping drivers for @@ -58,7 +58,7 @@ public function getDrivers(): array public function loadMetadataForClass(string $className, ClassMetadata $metadata): void { foreach ($this->drivers as $namespace => $driver) { - if (strpos($className, $namespace) === 0) { + if (str_starts_with($className, $namespace)) { $driver->loadMetadataForClass($className, $metadata); return; @@ -91,7 +91,7 @@ public function getAllClassNames(): array } foreach ($driverClasses[$oid] as $className) { - if (strpos($className, $namespace) !== 0) { + if (! str_starts_with($className, $namespace)) { continue; } @@ -112,7 +112,7 @@ public function getAllClassNames(): array public function isTransient(string $className): bool { foreach ($this->drivers as $namespace => $driver) { - if (strpos($className, $namespace) === 0) { + if (str_starts_with($className, $namespace)) { return $driver->isTransient($className); } } diff --git a/src/Mapping/Driver/SymfonyFileLocator.php b/src/Mapping/Driver/SymfonyFileLocator.php index 21473394..b7594ae6 100644 --- a/src/Mapping/Driver/SymfonyFileLocator.php +++ b/src/Mapping/Driver/SymfonyFileLocator.php @@ -48,9 +48,6 @@ final class SymfonyFileLocator implements FileLocator */ protected array $prefixes = []; - /** File extension that is searched for. */ - protected string|null $fileExtension; - /** * Represents PHP namespace delimiters when looking for files */ @@ -63,11 +60,11 @@ final class SymfonyFileLocator implements FileLocator */ public function __construct( array $prefixes, - string $fileExtension = '', + /** File extension that is searched for. */ + protected string|null $fileExtension = '', string $nsSeparator = '.', ) { $this->addNamespacePrefixes($prefixes); - $this->fileExtension = $fileExtension; if ($nsSeparator === '') { throw new InvalidArgumentException('Namespace separator should not be empty'); diff --git a/tests/Event/PreUpdateEventArgsTest.php b/tests/Event/PreUpdateEventArgsTest.php index fef09458..508af502 100644 --- a/tests/Event/PreUpdateEventArgsTest.php +++ b/tests/Event/PreUpdateEventArgsTest.php @@ -70,7 +70,7 @@ private function createTestPreUpdateEventArgs(): PreUpdateEventArgs { $entity = new TestObject(); - $objectManager = $this->createMock(ObjectManager::class); + $objectManager = self::createStub(ObjectManager::class); $entityChangeset = [ 'name' => ['old', 'new'], diff --git a/tests/ManagerRegistryTest.php b/tests/ManagerRegistryTest.php index 7f0d17ec..37ee415b 100644 --- a/tests/ManagerRegistryTest.php +++ b/tests/ManagerRegistryTest.php @@ -129,7 +129,7 @@ public function testResetManager(): void public function testGetRepository(): void { - $repository = $this->createMock(ObjectRepository::class); + $repository = self::createStub(ObjectRepository::class); $defaultManager = $this->mr->getManager(); assert($defaultManager instanceof MockObject); @@ -154,7 +154,7 @@ public function testGetRepositoryWithSpecificManagerName(): void $this->getManagerFactory(), ); - $repository = $this->createMock(ObjectRepository::class); + $repository = self::createStub(ObjectRepository::class); $defaultManager = $this->mr->getManager(); assert($defaultManager instanceof MockObject); @@ -185,7 +185,7 @@ public function testGetRepositoryWithManagerDetection(): void $this->getManagerFactory(), ); - $repository = $this->createMock(ObjectRepository::class); + $repository = self::createStub(ObjectRepository::class); $defaultManager = $this->mr->getManager(); assert($defaultManager instanceof MockObject); @@ -208,9 +208,10 @@ private function getManagerFactory(): Closure { return function (string $name) { $mock = $this->createMock(ObjectManager::class); + $mock->expects($this->never())->method('clear'); - $driver = $this->createMock(MappingDriver::class); - $metadata = $this->createMock(ClassMetadata::class); + $driver = self::createStub(MappingDriver::class); + $metadata = self::createStub(ClassMetadata::class); $metadata ->method('getName') diff --git a/tests/Mapping/AbstractClassMetadataFactoryTest.php b/tests/Mapping/AbstractClassMetadataFactoryTest.php index 45647138..c9b148e4 100644 --- a/tests/Mapping/AbstractClassMetadataFactoryTest.php +++ b/tests/Mapping/AbstractClassMetadataFactoryTest.php @@ -29,7 +29,7 @@ public function testItSkipsTransientClasses(): void $cmf = $this->createTestFactory($driver); $metadataCallCount = 0; - $cmf->newClassMetadataInstanceCallback = function ($className) use (&$metadataCallCount) { + $cmf->newClassMetadataInstanceCallback = static function ($className) use (&$metadataCallCount) { $metadataCallCount++; if ($metadataCallCount === 1) { self::assertEquals(SomeGrandParentEntity::class, $className); @@ -37,7 +37,7 @@ public function testItSkipsTransientClasses(): void self::assertEquals(SomeEntity::class, $className); } - return $this->createMock(ClassMetadata::class); + return self::createStub(ClassMetadata::class); }; $driverCallCount = 0; @@ -71,7 +71,7 @@ public function testItThrowsWhenAttemptingToGetMetadataForAnonymousClass(): void public function testAnonymousClassIsNotMistakenForShortAlias(): void { - $driver = $this->createMock(MappingDriver::class); + $driver = self::createStub(MappingDriver::class); $driver->method('isTransient')->willReturn(false); $cmf = $this->createTestFactory($driver); @@ -97,7 +97,7 @@ public function testItThrowsWhenAttemptingToCheckTransientForShortAlias(): void public function testItGetsTheSameMetadataForBackslashedClassName(): void { - $driver = $this->createMock(MappingDriver::class); + $driver = self::createStub(MappingDriver::class); $cmf = $this->createTestFactory($driver); $metadata = self::createStub(ClassMetadata::class); @@ -135,8 +135,8 @@ class TestAbstractClassMetadataFactory extends AbstractClassMetadataFactory /** @param ClassMetadata|null $defaultMetadata */ public function __construct( - private MappingDriver|null $driver = null, - private ClassMetadata|null $defaultMetadata = null, + private readonly MappingDriver|null $driver = null, + private readonly ClassMetadata|null $defaultMetadata = null, ) { } diff --git a/tests/Mapping/ClassMetadataFactoryTest.php b/tests/Mapping/ClassMetadataFactoryTest.php index d8a6346a..c6608501 100644 --- a/tests/Mapping/ClassMetadataFactoryTest.php +++ b/tests/Mapping/ClassMetadataFactoryTest.php @@ -28,10 +28,10 @@ class ClassMetadataFactoryTest extends TestCase #[Override] protected function setUp(): void { - $driver = $this->createMock(MappingDriver::class); + $driver = self::createStub(MappingDriver::class); /** @phpstan-var ClassMetadata */ - $metadata = $this->createMock(ClassMetadata::class); + $metadata = self::createStub(ClassMetadata::class); $this->cmf = new TestClassMetadataFactory($driver, $metadata); } @@ -67,7 +67,7 @@ public function testGetParentMetadata(): void public function testGetCachedMetadata(): void { - $metadata = $this->createMock(ClassMetadata::class); + $metadata = self::createStub(ClassMetadata::class); $cache = new ArrayAdapter(); $item = $cache->getItem($this->cmf->getCacheKey(ChildEntity::class)); $item->set($metadata); @@ -92,7 +92,7 @@ public function testCacheGetMetadataFor(): void public function testWillFallbackOnNotLoadedMetadata(): void { - $classMetadata = $this->createMock(ClassMetadata::class); + $classMetadata = self::createStub(ClassMetadata::class); $this->cmf->fallbackCallback = static fn () => $classMetadata; diff --git a/tests/Mapping/DriverChainTest.php b/tests/Mapping/DriverChainTest.php index 66ce22f2..141f6cea 100644 --- a/tests/Mapping/DriverChainTest.php +++ b/tests/Mapping/DriverChainTest.php @@ -22,7 +22,7 @@ class DriverChainTest extends TestCase public function testDelegateToMatchingNamespaceDriver(string $namespace1, string $namespace2): void { $className = DriverChainEntity::class; - $classMetadata = $this->createMock(ClassMetadata::class); + $classMetadata = self::createStub(ClassMetadata::class); $chain = new MappingDriverChain(); @@ -52,7 +52,7 @@ public function testDelegateToMatchingNamespaceDriver(string $namespace1, string public function testLoadMetadataShouldThrowMappingExceptionWhenNoDelegatorWasFound(): void { $className = DriverChainEntity::class; - $classMetadata = $this->createMock(ClassMetadata::class); + $classMetadata = self::createStub(ClassMetadata::class); $chain = new MappingDriverChain(); @@ -87,7 +87,7 @@ public function testGatherAllClassNames(): void #[Group('DDC-706')] public function testIsTransient(): void { - $driver1 = $this->createMock(MappingDriver::class); + $driver1 = self::createStub(MappingDriver::class); $chain = new MappingDriverChain(); $chain->addDriver($driver1, 'Doctrine\Tests\Models\CMS'); diff --git a/tests/Mapping/FileDriverTest.php b/tests/Mapping/FileDriverTest.php index 6018fd2d..7ea523c5 100644 --- a/tests/Mapping/FileDriverTest.php +++ b/tests/Mapping/FileDriverTest.php @@ -13,6 +13,7 @@ use Doctrine\Tests\Persistence\Mapping\Fixtures\TestClassMetadata; use Override; use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\MockObject\Stub; use PHPUnit\Framework\TestCase; use stdClass; @@ -44,7 +45,7 @@ public function testGetElementFromGlobalFile(): void public function testGetElementFromFile(): void { - $locator = $this->newLocator(); + $locator = $this->newLocator(true); $locator->expects(self::once()) ->method('findMappingFile') ->with(self::equalTo(stdClass::class)) @@ -57,7 +58,7 @@ public function testGetElementFromFile(): void public function testGetElementUpdatesClassCache(): void { - $locator = $this->newLocator(); + $locator = $this->newLocator(true); // findMappingFile should only be called once $locator->expects(self::once()) @@ -119,7 +120,7 @@ public function testGetAllClassNamesBothSources(): void public function testGetAllClassNamesBothSourcesNoDupes(): void { - $locator = $this->newLocator(); + $locator = $this->newLocator(true); $locator->expects(self::once()) ->method('getAllClassNames') ->with(self::equalTo('global')) @@ -139,7 +140,7 @@ public function testGetAllClassNamesBothSourcesNoDupes(): void public function testIsNotTransient(): void { - $locator = $this->newLocator(); + $locator = $this->newLocator(true); $locator->expects(self::once()) ->method('fileExists') ->with(self::equalTo(stdClass::class)) @@ -155,7 +156,7 @@ public function testIsNotTransient(): void public function testIsTransient(): void { - $locator = $this->newLocator(); + $locator = $this->newLocator(true); $locator->expects(self::once()) ->method('fileExists') ->with(self::equalTo(NotLoadedClass::class)) @@ -173,10 +174,10 @@ public function testNonLocatorFallback(): void self::assertFalse($driver->isTransient(stdClass::class)); } - /** @return FileLocator&MockObject */ - private function newLocator(): MockObject + /** @return ($mock is true ? (FileLocator&MockObject) : (FileLocator&Stub)) */ + private function newLocator(bool $mock = false): FileLocator { - $locator = $this->createMock(FileLocator::class); + $locator = $mock ? $this->createMock(FileLocator::class) : self::createStub(FileLocator::class); $locator->method('getFileExtension')->willReturn('.yml'); $locator->method('getPaths')->willReturn([__DIR__ . '/_files']); @@ -188,9 +189,9 @@ private function createTestFileDriver(string|array|FileLocator $locator, string| { $driver = new TestFileDriver($locator, $fileExtension); - $driver->stdClass = $this->createMock(ClassMetadata::class); - $driver->stdGlobal = $this->createMock(ClassMetadata::class); - $driver->stdGlobal2 = $this->createMock(ClassMetadata::class); + $driver->stdClass = self::createStub(ClassMetadata::class); + $driver->stdGlobal = self::createStub(ClassMetadata::class); + $driver->stdGlobal2 = self::createStub(ClassMetadata::class); return $driver; } diff --git a/tests/Mapping/RuntimeReflectionServiceTest.php b/tests/Mapping/RuntimeReflectionServiceTest.php index e9f18235..4d439e1d 100644 --- a/tests/Mapping/RuntimeReflectionServiceTest.php +++ b/tests/Mapping/RuntimeReflectionServiceTest.php @@ -22,9 +22,11 @@ class RuntimeReflectionServiceTest extends TestCase public mixed $unusedPublicProperty; - private string $typedNoDefaultProperty; + /** @phpstan-ignore property.uninitializedReadonly */ + private readonly string $typedNoDefaultProperty; private string $typedDefaultProperty = ''; - private string $nonTypedNoDefaultProperty; // phpcs:ignore SlevomatCodingStandard.Classes.UnusedPrivateElements.UnusedProperty + /** @phpstan-ignore property.uninitializedReadonly */ + private readonly string $nonTypedNoDefaultProperty; // phpcs:ignore SlevomatCodingStandard.Classes.UnusedPrivateElements.UnusedProperty private string $nonTypedDefaultProperty = ''; // phpcs:ignore SlevomatCodingStandard.Classes.UnusedPrivateElements.UnusedProperty public string $typedNoDefaultPublicProperty; diff --git a/tests/ObjectManagerDecoratorTest.php b/tests/ObjectManagerDecoratorTest.php index 4f15d53c..8b2c170d 100644 --- a/tests/ObjectManagerDecoratorTest.php +++ b/tests/ObjectManagerDecoratorTest.php @@ -100,7 +100,7 @@ public function testFlush(): void public function testGetRepository(): void { - $repository = $this->createMock(ObjectRepository::class); + $repository = self::createStub(ObjectRepository::class); $this->wrapped->expects(self::once()) ->method('getRepository') @@ -112,7 +112,7 @@ public function testGetRepository(): void public function testGetClassMetadata(): void { - $classMetadata = $this->createMock(ClassMetadata::class); + $classMetadata = self::createStub(ClassMetadata::class); $this->wrapped->expects(self::once()) ->method('getClassMetadata') @@ -124,7 +124,7 @@ public function testGetClassMetadata(): void public function testGetClassMetadataFactory(): void { - $classMetadataFactory = $this->createMock(ClassMetadataFactory::class); + $classMetadataFactory = self::createStub(ClassMetadataFactory::class); $this->wrapped->expects(self::once()) ->method('getMetadataFactory') diff --git a/tests/Reflection/TypedNoDefaultReflectionPropertyTest.php b/tests/Reflection/TypedNoDefaultReflectionPropertyTest.php index 3b3f41ee..244adff7 100644 --- a/tests/Reflection/TypedNoDefaultReflectionPropertyTest.php +++ b/tests/Reflection/TypedNoDefaultReflectionPropertyTest.php @@ -72,7 +72,7 @@ public function setId(mixed $id): void class TypedNullableFoo { - private string|null $value; + private string|null $value = null; public function setValue(mixed $value): void { diff --git a/tests/RuntimeReflectionPropertyTest.php b/tests/RuntimeReflectionPropertyTest.php index 90a7241d..030de88a 100644 --- a/tests/RuntimeReflectionPropertyTest.php +++ b/tests/RuntimeReflectionPropertyTest.php @@ -40,8 +40,8 @@ public function testGetSetValue(string $name, string $value): void } /** @param class-string $proxyClass */ - #[TestWith(['Doctrine\\Tests\\Persistence\\RuntimeReflectionPropertyTestProxyMock'])] - #[TestWith(['\\Doctrine\\Tests\\Persistence\\RuntimeReflectionPropertyTestProxyMock'])] + #[TestWith([RuntimeReflectionPropertyTestProxyMock::class])] + #[TestWith([RuntimeReflectionPropertyTestProxyMock::class])] public function testGetValueOnProxyProperty(string $proxyClass): void { $getCheckMock = $this->createMock(DummyMock::class);