Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support DBAL 4 and ORM 3 #452

Merged
merged 1 commit into from
Nov 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,21 @@
"doctrine/persistence": "^2.0|^3.0"
},
"conflict": {
"doctrine/dbal": "<3",
"doctrine/orm": "<2.14",
"doctrine/dbal": "<3.5 || >=5",
"doctrine/orm": "<2.14 || >=4",
"doctrine/phpcr-odm": "<1.3.0"
},
"require-dev": {
"ext-sqlite3": "*",
"doctrine/coding-standard": "^11.1",
"doctrine/dbal": "^3.0",
"doctrine/annotations": "^1.12 || ^2",
"doctrine/coding-standard": "^12",
"doctrine/dbal": "^3.5 || ^4",
"doctrine/mongodb-odm": "^1.3.0 || ^2.0.0",
"doctrine/orm": "^2.14",
"doctrine/orm": "^2.14 || ^3",
"phpstan/phpstan": "^1.10",
"phpunit/phpunit": "^9.6.6 || ^10.0",
"symfony/cache": "^5.4 || ^6.2",
"phpunit/phpunit": "^9.6.13 || ^10.4.2",
"symfony/cache": "^5.4 || ^6.3 || ^7",
"symfony/var-exporter": "^5.4 || ^6.3 || ^7",
"vimeo/psalm": "^5.9"
},
"suggest": {
Expand Down
4 changes: 4 additions & 0 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,9 @@ parameters:
- src
- tests

ignoreErrors:
# ORM 3 forward compatibility
- '~^Parameter \$assoc of method Doctrine\\Common\\DataFixtures\\Purger\\ORMPurger\:\:getJoinTableName\(\) has invalid type Doctrine\\ORM\\Mapping\\ManyToManyOwningSideMapping\.$~'

includes:
- phpstan-baseline.neon
9 changes: 9 additions & 0 deletions psalm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,13 @@
<directory name="vendor" />
</ignoreFiles>
</projectFiles>

<issueHandlers>
<UndefinedDocblockClass>
<errorLevel type="suppress">
<!-- ORM 3 forward compatibility -->
<referencedClass name="Doctrine\ORM\Mapping\ManyToManyOwningSideMapping" />
</errorLevel>
</UndefinedDocblockClass>
</issueHandlers>
</psalm>
2 changes: 1 addition & 1 deletion src/AbstractFixture.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ abstract class AbstractFixture implements SharedFixtureInterface
protected $referenceRepository;

/**
* {@inheritdoc}
* {@inheritDoc}
*/
public function setReferenceRepository(ReferenceRepository $referenceRepository)
{
Expand Down
2 changes: 1 addition & 1 deletion src/Event/Listener/MongoDBReferenceListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public function __construct(ReferenceRepository $referenceRepository)
}

/**
* {@inheritdoc}
* {@inheritDoc}
*/
public function getSubscribedEvents(): array
{
Expand Down
6 changes: 3 additions & 3 deletions src/Event/Listener/ORMReferenceListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use Doctrine\Common\DataFixtures\ReferenceRepository;
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Event\PostPersistEventArgs;

use function get_class;

Expand All @@ -24,7 +24,7 @@ public function __construct(ReferenceRepository $referenceRepository)
}

/**
* {@inheritdoc}
* {@inheritDoc}
*/
public function getSubscribedEvents(): array
{
Expand All @@ -35,7 +35,7 @@ public function getSubscribedEvents(): array
/**
* Populates identities for stored references
*/
public function postPersist(LifecycleEventArgs $args): void
public function postPersist(PostPersistEventArgs $args): void
{
$object = $args->getObject();

Expand Down
5 changes: 3 additions & 2 deletions src/Purger/ORMPurger.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Doctrine\DBAL\Schema\Identifier;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Mapping\ManyToManyOwningSideMapping;

use function array_map;
use function array_reverse;
Expand Down Expand Up @@ -256,9 +257,9 @@ private function getTableName(ClassMetadata $class, AbstractPlatform $platform):
return $this->em->getConfiguration()->getQuoteStrategy()->getTableName($class, $platform);
}

/** @param mixed[] $assoc */
/** @param ManyToManyOwningSideMapping|mixed[] $assoc */
private function getJoinTableName(
array $assoc,
$assoc,
ClassMetadata $class,
AbstractPlatform $platform
): string {
Expand Down
37 changes: 21 additions & 16 deletions tests/Common/DataFixtures/BaseTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,33 +9,38 @@
use Doctrine\ORM\ORMSetup;
use PHPUnit\Framework\TestCase;

use function method_exists;

use const PHP_VERSION_ID;

/**
* Base test class
*/
abstract class BaseTestCase extends TestCase
{
/**
* EntityManager mock object together with
* annotation mapping driver
*/
protected function getMockAnnotationReaderEntityManager(): EntityManager
{
$dbParams = ['driver' => 'pdo_sqlite', 'memory' => true];
$config = ORMSetup::createAnnotationMetadataConfiguration([__DIR__ . '/TestEntity'], true);

return new EntityManager(DriverManager::getConnection($dbParams, $config), $config);
}

/**
* EntityManager mock object together with
* annotation mapping driver and pdo_sqlite
* database in memory
*/
protected function getMockSqliteEntityManager(): EntityManager
protected function getMockSqliteEntityManager(string $fixtureSet = 'TestEntity'): EntityManager
{
$dbParams = ['driver' => 'pdo_sqlite', 'memory' => true];
$config = ORMSetup::createAnnotationMetadataConfiguration([__DIR__ . '/TestEntity'], true);
$dbParams = ['driver' => 'sqlite3', 'memory' => true];
if (PHP_VERSION_ID >= 80100) {
$config = ORMSetup::createAttributeMetadataConfiguration([__DIR__ . '/' . $fixtureSet], true);
$config->setLazyGhostObjectEnabled(true);
} else {
$config = ORMSetup::createAnnotationMetadataConfiguration([__DIR__ . '/' . $fixtureSet], true);
}

$connection = DriverManager::getConnection($dbParams, $config);
$platform = $connection->getDatabasePlatform();
if (method_exists($platform, 'disableSchemaEmulation')) {
$platform->disableSchemaEmulation();
}

$connection->executeStatement('ATTACH DATABASE \':memory:\' AS readers');

return new EntityManager(DriverManager::getConnection($dbParams, $config), $config);
return new EntityManager($connection, $config);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
use Doctrine\Tests\Common\DataFixtures\TestEntity\User;
use PHPUnit\Framework\MockObject\MockObject;

use function extension_loaded;

/**
* Test referenced fixture execution
*/
Expand All @@ -24,7 +22,7 @@ class ORMExecutorSharedFixtureTest extends BaseTestCase

public function testFixtureExecution(): void
{
$em = $this->getMockAnnotationReaderEntityManager();
$em = $this->getMockSqliteEntityManager();
$purger = new ORMPurger();
$executor = new ORMExecutor($em, $purger);

Expand All @@ -43,10 +41,6 @@ public function testFixtureExecution(): void

public function testSharedFixtures(): void
{
if (! extension_loaded('pdo_sqlite')) {
$this->markTestSkipped('Missing pdo_sqlite extension.');
}

$em = $this->getMockSqliteEntityManager();
$schemaTool = new SchemaTool($em);
$schemaTool->dropSchema([]);
Expand Down
17 changes: 9 additions & 8 deletions tests/Common/DataFixtures/Executor/ORMExecutorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use Doctrine\Common\EventManager;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\Tests\Common\DataFixtures\BaseTestCase;
use Doctrine\Tests\Mock\ForwardCompatibleEntityManager;
use PHPUnit\Framework\MockObject\MockObject;

/**
Expand All @@ -38,8 +39,8 @@ public function testExecuteSingleTransactionsCountTransactionalCalls(): void
{
$em = $this->getMockEntityManager();
$em->method('getEventManager')->willReturn($this->createMock(EventManager::class));
// We call transactional once for purge and for the fixtures (load)
$em->expects($this->once())->method('transactional')->with(self::isInstanceOf(Closure::class));
// We call wrapInTransaction once for purge and for the fixtures (load)
$em->expects($this->once())->method('wrapInTransaction')->with(self::isInstanceOf(Closure::class));

$executor = new ORMExecutor($em);
$fixture = $this->getMockFixture();
Expand All @@ -52,7 +53,7 @@ public function testExecuteWithPurge(): void
$purger = $this->getMockPurger();
$purger->expects($this->once())
->method('purge')
->will($this->returnValue(null));
->willReturn(null);
$executor = new ORMExecutor($em, $purger);
$fixture = $this->getMockFixture();
$fixture->expects($this->once())
Expand All @@ -76,7 +77,7 @@ public function testCustomLegacyEntityManager(): void
{
$em = $this->getMockEntityManager();
$em->method('getEventManager')->willReturn($this->createMock(EventManager::class));
$em->expects($this->once())->method('transactional')->with(self::isInstanceOf(Closure::class));
$em->expects($this->once())->method('wrapInTransaction')->with(self::isInstanceOf(Closure::class));

$executor = new ORMExecutor($em);
@$executor->execute([]);
Expand All @@ -103,7 +104,7 @@ public function testExecuteMultipleTransactionsWithPurge(): void
$purger = $this->getMockPurger();
$purger->expects($this->once())
->method('purge')
->will($this->returnValue(null));
->willReturn(null);
$executor = new MultipleTransactionORMExecutor($em, $purger);
$fixture = $this->getMockFixture();
$fixture->expects($this->once())
Expand All @@ -116,8 +117,8 @@ public function testExecuteMultipleTransactionsCountTransactionalCalls(): void
{
$em = $this->getMockEntityManager();
$em->method('getEventManager')->willReturn($this->createMock(EventManager::class));
// We call transactional once for purge and twice for the fixtures (load)
$em->expects($this->exactly(3))->method('transactional')->with(self::isInstanceOf(Closure::class));
// We call wrapInTransaction once for purge and twice for the fixtures (load)
$em->expects($this->exactly(3))->method('wrapInTransaction')->with(self::isInstanceOf(Closure::class));

$executor = new MultipleTransactionORMExecutor($em);
$fixture = $this->getMockFixture();
Expand All @@ -127,7 +128,7 @@ public function testExecuteMultipleTransactionsCountTransactionalCalls(): void
/** @return EntityManagerInterface&MockObject */
private function getMockEntityManager(): EntityManagerInterface
{
return $this->createMock(EntityManagerInterface::class);
return $this->createMock(ForwardCompatibleEntityManager::class);
}

/** @return FixtureInterface&MockObject */
Expand Down
2 changes: 1 addition & 1 deletion tests/Common/DataFixtures/ProxyReferenceRepositoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public static function setUpBeforeClass(): void

public function testReferenceEntry(): void
{
$em = $this->getMockAnnotationReaderEntityManager();
$em = $this->getMockSqliteEntityManager();
$role = new TestEntity\Role();
$role->setName('admin');
$meta = $em->getClassMetadata(self::TEST_ENTITY_ROLE);
Expand Down
11 changes: 1 addition & 10 deletions tests/Common/DataFixtures/Purger/ORMPurgerExcludeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,12 @@
namespace Doctrine\Tests\Common\DataFixtures;

use Doctrine\Common\DataFixtures\Purger\ORMPurger;
use Doctrine\DBAL\DriverManager;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\ORMSetup;
use Doctrine\ORM\Tools\SchemaTool;
use Doctrine\Tests\Common\DataFixtures\TestPurgeEntity\ExcludedEntity;
use Doctrine\Tests\Common\DataFixtures\TestPurgeEntity\IncludedEntity;

use function count;
use function extension_loaded;
use function preg_match;

class ORMPurgerExcludeTest extends BaseTestCase
Expand All @@ -26,13 +23,7 @@ class ORMPurgerExcludeTest extends BaseTestCase
*/
protected function loadTestData(): EntityManager
{
if (! extension_loaded('pdo_sqlite')) {
$this->markTestSkipped('Missing pdo_sqlite extension.');
}

$dbParams = ['driver' => 'pdo_sqlite', 'memory' => true];
$config = ORMSetup::createAnnotationMetadataConfiguration([__DIR__ . '/../TestPurgeEntity'], true);
$em = new EntityManager(DriverManager::getConnection($dbParams, $config), $config);
$em = $this->getMockSqliteEntityManager('TestPurgeEntity');

$schemaTool = new SchemaTool($em);
$schemaTool->dropDatabase();
Expand Down
14 changes: 7 additions & 7 deletions tests/Common/DataFixtures/Purger/ORMPurgerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,20 @@ class ORMPurgerTest extends BaseTestCase

public function testGetAssociationTables(): void
{
$em = $this->getMockAnnotationReaderEntityManager();
$em = $this->getMockSqliteEntityManager();
$metadata = $em->getClassMetadata(self::TEST_ENTITY_USER);
$platform = $em->getConnection()->getDatabasePlatform();
$purger = new ORMPurger($em);
$class = new ReflectionClass(ORMPurger::class);
$method = $class->getMethod('getAssociationTables');
$method->setAccessible(true);
$associationTables = $method->invokeArgs($purger, [[$metadata], $platform]);
$this->assertEquals($associationTables[0], 'readers__author_reader');
$this->assertEquals('readers.author_reader', $associationTables[0]);
}

public function testGetAssociationTablesQuoted(): void
{
$em = $this->getMockAnnotationReaderEntityManager();
$em = $this->getMockSqliteEntityManager();
$metadata = $em->getClassMetadata(self::TEST_ENTITY_QUOTED);
$platform = $em->getConnection()->getDatabasePlatform();
$purger = new ORMPurger($em);
Expand All @@ -46,7 +46,7 @@ public function testGetAssociationTablesQuoted(): void

public function testTableNameWithSchema(): void
{
$em = $this->getMockAnnotationReaderEntityManager();
$em = $this->getMockSqliteEntityManager();
$metadata = $em->getClassMetadata(self::TEST_ENTITY_USER_WITH_SCHEMA);
$platform = $em->getConnection()->getDatabasePlatform();
$purger = new ORMPurger($em);
Expand All @@ -59,7 +59,7 @@ public function testTableNameWithSchema(): void

public function testGetDeleteFromTableSQL(): void
{
$em = $this->getMockAnnotationReaderEntityManager();
$em = $this->getMockSqliteEntityManager();
$metadata = $em->getClassMetadata(self::TEST_ENTITY_GROUP);
$platform = $em->getConnection()->getDatabasePlatform();
$purger = new ORMPurger($em);
Expand All @@ -75,7 +75,7 @@ public function testGetDeleteFromTableSQL(): void

public function testGetDeleteFromTableSQLWithSchema(): void
{
$em = $this->getMockAnnotationReaderEntityManager();
$em = $this->getMockSqliteEntityManager();
$metadata = $em->getClassMetadata(self::TEST_ENTITY_GROUP_WITH_SCHEMA);
$platform = $em->getConnection()->getDatabasePlatform();
$purger = new ORMPurger($em);
Expand All @@ -86,6 +86,6 @@ public function testGetDeleteFromTableSQLWithSchema(): void
$method = $class->getMethod('getDeleteFromTableSQL');
$method->setAccessible(true);
$sql = $method->invokeArgs($purger, [$tableName, $platform]);
$this->assertEquals('DELETE FROM test_schema__group', $sql);
$this->assertEquals('DELETE FROM test_schema."group"', $sql);
}
}
8 changes: 4 additions & 4 deletions tests/Common/DataFixtures/ReferenceRepositoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,19 @@
use BadMethodCallException;
use Doctrine\Common\DataFixtures\Event\Listener\ORMReferenceListener;
use Doctrine\Common\DataFixtures\ReferenceRepository;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Tools\SchemaTool;
use Doctrine\ORM\UnitOfWork;
use Doctrine\Persistence\Mapping\ClassMetadata;
use Doctrine\Persistence\Proxy;
use Doctrine\Tests\Common\DataFixtures\TestEntity\Role;
use Doctrine\Tests\Mock\ForwardCompatibleEntityManager;
use OutOfBoundsException;

class ReferenceRepositoryTest extends BaseTestCase
{
public function testReferenceEntry(): void
{
$em = $this->getMockAnnotationReaderEntityManager();
$em = $this->getMockSqliteEntityManager();

$role = new TestEntity\Role();
$role->setName('admin');
Expand Down Expand Up @@ -199,7 +199,7 @@ public function testGetIdentifierWhenHasNotBeenManagedYetByUnitOfWork(): void
->with($role)
->willReturn($identitiesExpected);

$em = $this->createMock(EntityManagerInterface::class);
$em = $this->createMock(ForwardCompatibleEntityManager::class);
$em->method('getUnitOfWork')
->willReturn($uow);
$em->method('getClassMetadata')
Expand Down
Loading