Merge pull request #574 from greg0ire/maintenance

Maintenance
This commit is contained in:
Grégoire Paris
2025-10-13 07:50:40 +02:00
committed by GitHub
14 changed files with 150 additions and 42 deletions

View File

@@ -33,7 +33,7 @@
"doctrine/orm": "^2.14 || ^3",
"fig/log-test": "^1",
"phpstan/phpstan": "2.1.30",
"phpunit/phpunit": "^9.6.13 || 10.5.45",
"phpunit/phpunit": "^9.6.13 || ^12.4",
"psr/log": "^1.1 || ^2 || ^3",
"symfony/cache": "^5.4 || ^6.3 || ^7",
"symfony/var-exporter": "^5.4 || ^6.3 || ^7"

View File

@@ -306,6 +306,12 @@ parameters:
count: 1
path: src/Sorter/Vertex.php
-
message: '#^Call to function method_exists\(\) with ''Doctrine\\\\ORM\\\\ORMSetup'' and ''createAttributeMeta…'' will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType
count: 1
path: tests/Common/DataFixtures/BaseTestCase.php
-
message: '#^Method Doctrine\\Tests\\Common\\DataFixtures\\FixtureWithUnexistentDependency\:\:getDependencies\(\) should return array\<class\-string\<Doctrine\\Common\\DataFixtures\\FixtureInterface\>\> but returns array\<int, string\>\.$#'
identifier: return.type
@@ -318,6 +324,12 @@ parameters:
count: 5
path: tests/Common/DataFixtures/Executor/PHPCRExecutorTest.php
-
message: '#^Call to function method_exists\(\) with ''Doctrine\\\\ORM\\\\ORMSetup'' and ''createAttributeMeta…'' will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType
count: 2
path: tests/Common/DataFixtures/ProxyReferenceRepositoryTest.php
-
message: '#^Call to an undefined method Doctrine\\ODM\\MongoDB\\DocumentManager\:\:getConnection\(\)\.$#'
identifier: method.notFound
@@ -330,6 +342,12 @@ parameters:
count: 1
path: tests/Common/DataFixtures/Purger/MongoDBPurgerTest.php
-
message: '#^Call to function method_exists\(\) with ''Doctrine\\\\ORM\\\\ORMSetup'' and ''createAttributeMeta…'' will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType
count: 2
path: tests/Common/DataFixtures/ReferenceRepositoryTest.php
-
message: '#^Parameter \#1 \$name of class Doctrine\\ORM\\Mapping\\ClassMetadata constructor expects class\-string\<1\>, string given\.$#'
identifier: argument.type

View File

@@ -1,5 +1,5 @@
parameters:
phpVersion: 80200
phpVersion: 80400
level: 7
paths:
- src

View File

@@ -3,8 +3,6 @@
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
colors="true"
beStrictAboutOutputDuringTests="true"
beStrictAboutTodoAnnotatedTests="true"
bootstrap="vendor/autoload.php"
>
<testsuites>
<testsuite name="Doctrine Data Fixtures Test Suite">
@@ -12,9 +10,13 @@
</testsuite>
</testsuites>
<coverage>
<php>
<server name="DOCTRINE_DEPRECATIONS" value="trigger"/>
</php>
<source ignoreSuppressionOfDeprecations="true">
<include>
<directory>./src</directory>
<directory>./src/</directory>
</include>
</coverage>
</source>
</phpunit>

View File

@@ -6,6 +6,7 @@ namespace Doctrine\Common\DataFixtures\Purger;
use Doctrine\Common\DataFixtures\Sorter\TopologicalSorter;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Schema\AbstractNamedObject;
use Doctrine\DBAL\Schema\Identifier;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Mapping\ClassMetadata;
@@ -13,6 +14,7 @@ use Doctrine\ORM\Mapping\ManyToManyOwningSideMapping;
use function array_map;
use function array_reverse;
use function class_exists;
use function count;
use function in_array;
@@ -268,6 +270,12 @@ class ORMPurger implements PurgerInterface, ORMPurgerInterface
{
$tableIdentifier = new Identifier($tableName);
return 'DELETE FROM ' . $tableIdentifier->getQuotedName($platform);
if (class_exists(AbstractNamedObject::class)) {
$identifier = $tableIdentifier->getObjectName()->toSQL($platform);
} else {
$identifier = $tableIdentifier->getQuotedName($platform);
}
return 'DELETE FROM ' . $identifier;
}
}

View File

@@ -26,7 +26,10 @@ abstract class BaseTestCase extends TestCase
protected function getMockSqliteEntityManager(string $fixtureSet = 'TestEntity'): EntityManager
{
$dbParams = ['driver' => 'sqlite3', 'memory' => true];
if (PHP_VERSION_ID >= 80100) {
if (PHP_VERSION_ID >= 80400 && method_exists(ORMSetup::class, 'createAttributeMetadataConfig')) {
$config = ORMSetup::createAttributeMetadataConfig([__DIR__ . '/' . $fixtureSet], true);
$config->enableNativeLazyObjects(true);
} elseif (PHP_VERSION_ID >= 80100) {
$config = ORMSetup::createAttributeMetadataConfiguration([__DIR__ . '/' . $fixtureSet], true);
$config->setLazyGhostObjectEnabled(true);
} else {

View File

@@ -10,6 +10,7 @@ use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Common\DataFixtures\Purger\PurgerInterface;
use Doctrine\Deprecations\PHPUnit\VerifyDeprecations;
use Doctrine\Persistence\ObjectManager;
use PHPUnit\Framework\Attributes\IgnoreDeprecations;
use PHPUnit\Framework\TestCase;
use Psr\Log\Test\TestLogger;
@@ -48,6 +49,7 @@ final class AbstractExecutorTest extends TestCase
self::assertTrue($logger->hasDebugThatContains('purging database'));
}
#[IgnoreDeprecations]
public function testDeprecatedLoggerUsage(): void
{
$executor = $this->bootstrapExecutor();

View File

@@ -10,6 +10,7 @@ use Doctrine\Common\DataFixtures\SharedFixtureInterface;
use Doctrine\ORM\Tools\SchemaTool;
use Doctrine\Tests\Common\DataFixtures\TestEntity\Role;
use Doctrine\Tests\Common\DataFixtures\TestEntity\User;
use PHPUnit\Framework\Attributes\IgnoreDeprecations;
use PHPUnit\Framework\MockObject\MockObject;
/**
@@ -20,6 +21,7 @@ class ORMExecutorSharedFixtureTest extends BaseTestCase
public const TEST_ENTITY_ROLE = Role::class;
public const TEST_ENTITY_USER = User::class;
#[IgnoreDeprecations]
public function testFixtureExecution(): void
{
$em = $this->getMockSqliteEntityManager();
@@ -39,6 +41,7 @@ class ORMExecutorSharedFixtureTest extends BaseTestCase
$executor->execute([$fixture], true);
}
#[IgnoreDeprecations]
public function testSharedFixtures(): void
{
$em = $this->getMockSqliteEntityManager();
@@ -69,7 +72,7 @@ class ORMExecutorSharedFixtureTest extends BaseTestCase
$this->assertEquals('admin@example.com', $userReference->getEmail());
}
/** @group legacy */
#[IgnoreDeprecations]
public function testLegacySharedFixtures(): void
{
$em = $this->getMockSqliteEntityManager();

View File

@@ -11,16 +11,13 @@ use Doctrine\ODM\PHPCR\DocumentManager;
use Doctrine\Tests\Common\DataFixtures\BaseTestCase;
use Doctrine\Tests\Mock\PHPCRDocumentManager;
use Exception;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\MockObject\MockObject;
use Throwable;
use function class_exists;
/**
* Tests for {@see \Doctrine\Common\DataFixtures\Executor\PHPCRExecutor}
*
* @covers \Doctrine\Common\DataFixtures\Executor\PHPCRExecutor
*/
#[CoversClass(PHPCRExecutor::class)]
class PHPCRExecutorTest extends BaseTestCase
{
public function testExecuteSingleFixtureWithNoPurge(): void
@@ -34,9 +31,9 @@ class PHPCRExecutorTest extends BaseTestCase
->expects($this->once())
->method('transactional')
->with($this->isType('callable'))
->will($this->returnCallback(static function ($callback) use ($dm) {
->willReturnCallback(static function ($callback) use ($dm) {
return $callback($dm);
}));
});
$executor->execute([$fixture], true);
}
@@ -54,9 +51,9 @@ class PHPCRExecutorTest extends BaseTestCase
->expects($this->once())
->method('transactional')
->with($this->isType('callable'))
->will($this->returnCallback(static function ($callback) use ($dm) {
->willReturnCallback(static function ($callback) use ($dm) {
return $callback($dm);
}));
});
$executor->execute([$fixture1, $fixture2], true);
}
@@ -73,9 +70,9 @@ class PHPCRExecutorTest extends BaseTestCase
->expects($this->once())
->method('transactional')
->with($this->isType('callable'))
->will($this->returnCallback(static function ($callback) use ($dm) {
->willReturnCallback(static function ($callback) use ($dm) {
return $callback($dm);
}));
});
$purger->expects($this->once())->method('purge');
$executor->execute([$fixture], false);
@@ -93,9 +90,9 @@ class PHPCRExecutorTest extends BaseTestCase
->expects($this->once())
->method('transactional')
->with($this->isType('callable'))
->will($this->returnCallback(static function ($callback) use ($dm) {
->willReturnCallback(static function ($callback) use ($dm) {
return $callback($dm);
}));
});
$purger->expects($this->never())->method('purge');
$executor->execute([$fixture], true);

View File

@@ -7,12 +7,19 @@ namespace Doctrine\Tests\Common\DataFixtures;
use Doctrine\Common\DataFixtures\Event\Listener\ORMReferenceListener;
use Doctrine\Common\DataFixtures\ProxyReferenceRepository;
use Doctrine\DBAL\Types\Type;
use Doctrine\ORM\ORMSetup;
use Doctrine\ORM\Tools\SchemaTool;
use Doctrine\Persistence\Proxy;
use Doctrine\Tests\Common\DataFixtures\TestEntity\Link;
use Doctrine\Tests\Common\DataFixtures\TestEntity\Role;
use Doctrine\Tests\Common\DataFixtures\TestTypes\UuidType;
use Doctrine\Tests\Common\DataFixtures\TestValueObjects\Uuid;
use PHPUnit\Framework\Attributes\IgnoreDeprecations;
use ReflectionClass;
use function method_exists;
use const PHP_VERSION_ID;
/**
* Test ProxyReferenceRepository.
@@ -33,12 +40,15 @@ class ProxyReferenceRepositoryTest extends BaseTestCase
Type::addType('uuid', UuidType::class);
}
#[IgnoreDeprecations]
public function testReferenceEntry(): void
{
$em = $this->getMockSqliteEntityManager();
$role = new TestEntity\Role();
$role->setName('admin');
$meta = $em->getClassMetadata(self::TEST_ENTITY_ROLE);
// getPropertyAccessor() is not available with ORM < 3.4
$meta->getReflectionProperty('id')->setValue($role, 1);
$referenceRepo = new ProxyReferenceRepository($em);
@@ -53,7 +63,7 @@ class ProxyReferenceRepositoryTest extends BaseTestCase
$this->assertInstanceOf(self::TEST_ENTITY_ROLE, $referencesByClass[Role::class]['test']);
}
/** @group legacy */
#[IgnoreDeprecations]
public function testLegacyReferenceEntry(): void
{
$em = $this->getMockSqliteEntityManager();
@@ -91,7 +101,7 @@ class ProxyReferenceRepositoryTest extends BaseTestCase
$referenceRepository->expects($this->once())
->method('getReferenceNames')
->will($this->returnValue(['admin-role']));
->willReturn(['admin-role']);
$referenceRepository->expects($this->once())
->method('setReferenceIdentity')
@@ -119,7 +129,7 @@ class ProxyReferenceRepositoryTest extends BaseTestCase
// first test against managed state
$ref = $referenceRepository->getReference('admin-role', Role::class);
$this->assertNotInstanceOf(Proxy::class, $ref);
$this->assertNotProxy($ref);
// test reference reconstruction from serialized data (was managed)
$serializedData = $referenceRepository->serialize();
@@ -130,14 +140,14 @@ class ProxyReferenceRepositoryTest extends BaseTestCase
$ref = $proxyReferenceRepository->getReference('admin-role', Role::class);
// before clearing, the reference is not yet a proxy
$this->assertNotInstanceOf(Proxy::class, $ref);
$this->assertNotProxy($ref);
$this->assertInstanceOf(self::TEST_ENTITY_ROLE, $ref);
// now test reference reconstruction from identity
$em->clear();
$ref = $referenceRepository->getReference('admin-role', Role::class);
$this->assertInstanceOf(Proxy::class, $ref);
$this->assertProxy($ref);
// test reference reconstruction from serialized data (was identity)
$serializedData = $referenceRepository->serialize();
@@ -147,9 +157,10 @@ class ProxyReferenceRepositoryTest extends BaseTestCase
$ref = $proxyReferenceRepository->getReference('admin-role', Role::class);
$this->assertInstanceOf(Proxy::class, $ref);
$this->assertProxy($ref);
}
#[IgnoreDeprecations]
public function testReconstructionOfCustomTypedId(): void
{
$em = $this->getMockSqliteEntityManager();
@@ -196,7 +207,31 @@ class ProxyReferenceRepositoryTest extends BaseTestCase
$em->flush();
$em->clear();
$this->assertInstanceOf(Proxy::class, $referenceRepository->getReference('admin', Role::class));
$this->assertInstanceOf(Proxy::class, $referenceRepository->getReference('duplicate', Role::class));
$this->assertProxy($referenceRepository->getReference('admin', Role::class));
$this->assertProxy($referenceRepository->getReference('duplicate', Role::class));
}
private function assertProxy(object $object): void
{
if (PHP_VERSION_ID < 80400 || ! method_exists(ORMSetup::class, 'createAttributeMetadataConfig')) {
$this->assertInstanceOf(Proxy::class, $object);
return;
}
$reflector = new ReflectionClass($object);
$this->assertTrue($reflector->isUninitializedLazyObject($object));
}
private function assertNotProxy(object $object): void
{
if (PHP_VERSION_ID < 80400 || ! method_exists(ORMSetup::class, 'createAttributeMetadataConfig')) {
$this->assertNotInstanceOf(Proxy::class, $object);
return;
}
$reflector = new ReflectionClass($object);
$this->assertFalse($reflector->isUninitializedLazyObject($object));
}
}

View File

@@ -5,8 +5,11 @@ declare(strict_types=1);
namespace Doctrine\Tests\Common\DataFixtures;
use Doctrine\Common\DataFixtures\Purger\ORMPurger;
use Doctrine\DBAL\Schema\AbstractNamedObject;
use ReflectionClass;
use function class_exists;
/**
* Doctrine\Tests\Common\DataFixtures\ORMPurgerTest
*/
@@ -86,6 +89,11 @@ class ORMPurgerTest extends BaseTestCase
$method = $class->getMethod('getDeleteFromTableSQL');
$method->setAccessible(true);
$sql = $method->invokeArgs($purger, [$tableName, $platform]);
$this->assertEquals('DELETE FROM test_schema."group"', $sql);
if (class_exists(AbstractNamedObject::class)) {
$this->assertEquals('DELETE FROM "test_schema"."group"', $sql);
} else {
$this->assertEquals('DELETE FROM test_schema."group"', $sql);
}
}
}

View File

@@ -8,17 +8,24 @@ use BadMethodCallException;
use Doctrine\Common\DataFixtures\Event\Listener\ORMReferenceListener;
use Doctrine\Common\DataFixtures\ReferenceRepository;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\ORMSetup;
use Doctrine\ORM\Tools\SchemaTool;
use Doctrine\ORM\UnitOfWork;
use Doctrine\Persistence\Proxy;
use Doctrine\Tests\Common\DataFixtures\TestEntity\Role;
use Doctrine\Tests\Mock\ForwardCompatibleEntityManager;
use OutOfBoundsException;
use PHPUnit\Framework\Attributes\IgnoreDeprecations;
use ReflectionClass;
use function method_exists;
use function sprintf;
use const PHP_VERSION_ID;
class ReferenceRepositoryTest extends BaseTestCase
{
#[IgnoreDeprecations]
public function testReferenceEntry(): void
{
$em = $this->getMockSqliteEntityManager();
@@ -42,7 +49,7 @@ class ReferenceRepositoryTest extends BaseTestCase
$this->assertInstanceOf(Role::class, $referencesByClass[Role::class]['test']);
}
/** @group legacy */
#[IgnoreDeprecations]
public function testLegacyReferenceEntry(): void
{
$em = $this->getMockSqliteEntityManager();
@@ -112,13 +119,13 @@ class ReferenceRepositoryTest extends BaseTestCase
// first test against managed state
$ref = $referenceRepository->getReference('admin-role', Role::class);
$this->assertNotInstanceOf(Proxy::class, $ref);
$this->assertNotProxy($ref);
// now test reference reconstruction from identity
$em->clear();
$ref = $referenceRepository->getReference('admin-role', Role::class);
$this->assertInstanceOf(Proxy::class, $ref);
$this->assertProxy($ref);
}
public function testReferenceMultipleEntries(): void
@@ -138,8 +145,8 @@ class ReferenceRepositoryTest extends BaseTestCase
$em->flush();
$em->clear();
$this->assertInstanceOf(Proxy::class, $referenceRepository->getReference('admin', Role::class));
$this->assertInstanceOf(Proxy::class, $referenceRepository->getReference('duplicate', Role::class));
$this->assertProxy($referenceRepository->getReference('admin', Role::class));
$this->assertProxy($referenceRepository->getReference('duplicate', Role::class));
}
public function testUndefinedReference(): void
@@ -152,7 +159,7 @@ class ReferenceRepositoryTest extends BaseTestCase
$referenceRepository->getReference('foo', Role::class);
}
/** @group legacy */
#[IgnoreDeprecations]
public function testLegacyUndefinedReference(): void
{
$referenceRepository = new ReferenceRepository($this->getMockSqliteEntityManager());
@@ -199,7 +206,7 @@ class ReferenceRepositoryTest extends BaseTestCase
$this->assertEquals(['entity' => 1], $referenceRepository->getIdentitiesByClass()[Role::class] ?? []);
}
/** @group legacy */
#[IgnoreDeprecations]
public function testLegacyHasIdentityCheck(): void
{
$role = new Role();
@@ -289,4 +296,28 @@ class ReferenceRepositoryTest extends BaseTestCase
$this->assertCount(1, $names);
$this->assertSame('1', $names[0]);
}
private function assertProxy(object $object): void
{
if (PHP_VERSION_ID < 80400 || ! method_exists(ORMSetup::class, 'createAttributeMetadataConfig')) {
$this->assertInstanceOf(Proxy::class, $object);
return;
}
$reflector = new ReflectionClass($object);
$this->assertTrue($reflector->isUninitializedLazyObject($object));
}
private function assertNotProxy(object $object): void
{
if (PHP_VERSION_ID < 80400 || ! method_exists(ORMSetup::class, 'createAttributeMetadataConfig')) {
$this->assertNotInstanceOf(Proxy::class, $object);
return;
}
$reflector = new ReflectionClass($object);
$this->assertFalse($reflector->isUninitializedLazyObject($object));
}
}

View File

@@ -8,6 +8,7 @@ use Doctrine\Common\DataFixtures\Exception\CircularReferenceException;
use Doctrine\Common\DataFixtures\Sorter\TopologicalSorter;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\Tests\Common\DataFixtures\BaseTestCase;
use PHPUnit\Framework\Attributes\CoversClass;
use RuntimeException;
/**
@@ -16,9 +17,8 @@ use RuntimeException;
* Note: When writing tests here consider that a lot of graph
* constellations can have many valid orderings, so you may want to
* build a graph that has only 1 valid order to simplify your tests
*
* @covers \Doctrine\Common\DataFixtures\Sorter\TopologicalSorter
*/
#[CoversClass(TopologicalSorter::class)]
class TopologicalSorterTest extends BaseTestCase
{
public function testSuccessSortLinearDependency(): void

View File

@@ -7,8 +7,9 @@ namespace Doctrine\Test\DataFixtures\Sorter;
use Doctrine\Common\DataFixtures\Sorter\Vertex;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\Tests\Common\DataFixtures\BaseTestCase;
use PHPUnit\Framework\Attributes\CoversClass;
/** @covers \Doctrine\Common\DataFixtures\Sorter\Vertex */
#[CoversClass(Vertex::class)]
class VertexTest extends BaseTestCase
{
public function testNode(): void