diff --git a/UPGRADE.md b/UPGRADE.md index b0ceb9235d6..9e63cab54f6 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -395,6 +395,10 @@ Use `toIterable()` instead. # Upgrade to 2.13 +## Deprecated passing `null` to `Doctrine\ORM\Query::setFirstResult()` + +`$query->setFirstResult(null);` is equivalent to `$query->setFirstResult(0)`. + ## Deprecated calling setters without arguments The following methods will require an argument in 3.0. Pass `null` instead of diff --git a/composer.json b/composer.json index 99d561ee631..a800c7d5a68 100644 --- a/composer.json +++ b/composer.json @@ -39,7 +39,7 @@ "doctrine/annotations": "^1.13", "doctrine/coding-standard": "^9.0", "phpbench/phpbench": "^1.0", - "phpstan/phpstan": "1.7.0", + "phpstan/phpstan": "1.7.9", "phpunit/phpunit": "^9.5", "psr/log": "^1 || ^2 || ^3", "squizlabs/php_codesniffer": "3.6.2", diff --git a/lib/Doctrine/ORM/AbstractQuery.php b/lib/Doctrine/ORM/AbstractQuery.php index da9c3590786..dee6e53eb25 100644 --- a/lib/Doctrine/ORM/AbstractQuery.php +++ b/lib/Doctrine/ORM/AbstractQuery.php @@ -397,8 +397,7 @@ public function setParameter($key, $value, $type = null) * * @param mixed $value * - * @return mixed[]|string|int|float|bool|object|null - * @psalm-return array|scalar|object|null + * @return mixed * * @throws ORMInvalidArgumentException */ diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php index bcdbf6c12eb..68139e2451e 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php @@ -95,6 +95,41 @@ * declaredField?: string, * options?: array * } + * @psalm-type AssociationMapping = array{ + * cache?: array, + * cascade?: array, + * declared?: class-string, + * fetch?: mixed, + * fieldName: string, + * id?: bool, + * inherited?: class-string, + * indexBy?: string, + * inversedBy?: string|null, + * isCascadeRemove?: bool, + * isCascadePersist?: bool, + * isCascadeRefresh?: bool, + * isCascadeMerge?: bool, + * isCascadeDetach?: bool, + * isOnDeleteCascade?: bool, + * isOwningSide?: bool, + * joinColumns?: array, + * joinColumnFieldNames?: array, + * joinTable?: array, + * joinTableColumns?: list, + * mappedBy?: string|null, + * orderBy?: array, + * originalClass?: class-string, + * originalField?: string, + * orphanRemoval?: bool, + * relationToSourceKeyColumns?: array, + * relationToTargetKeyColumns?: array, + * sourceEntity?: class-string, + * sourceToTargetKeyColumns?: array, + * targetEntity: class-string, + * targetToSourceKeyColumns: array, + * type: int, + * unique?: bool, + * } */ class ClassMetadataInfo implements ClassMetadata { @@ -578,7 +613,7 @@ class ClassMetadataInfo implements ClassMetadata * ) * * - * @psalm-var array> + * @psalm-var array */ public $associationMappings = []; @@ -1317,7 +1352,7 @@ public function getFieldMapping($fieldName) * the object model. * * @return mixed[] The mapping. - * @psalm-return array + * @psalm-return AssociationMapping * * @throws MappingException */ @@ -1333,7 +1368,7 @@ public function getAssociationMapping($fieldName) /** * Gets all association mappings of the class. * - * @psalm-return array> + * @psalm-return array */ public function getAssociationMappings() { @@ -2565,7 +2600,7 @@ public function mapField(array $mapping) * Adds an association mapping without completing/validating it. * This is mainly used to add inherited association mappings to derived classes. * - * @psalm-param array $mapping + * @psalm-param AssociationMapping $mapping * * @return void * diff --git a/lib/Doctrine/ORM/Query.php b/lib/Doctrine/ORM/Query.php index ac2645e9f4c..046257b599b 100644 --- a/lib/Doctrine/ORM/Query.php +++ b/lib/Doctrine/ORM/Query.php @@ -27,6 +27,7 @@ use function count; use function get_debug_type; use function in_array; +use function is_int; use function ksort; use function md5; use function reset; @@ -479,7 +480,7 @@ public function useQueryCache($bool): self /** * Defines how long the query cache will be active before expire. * - * @param int $timeToLive How long the cache entry is valid. + * @param int|null $timeToLive How long the cache entry is valid. * * @return $this */ @@ -599,7 +600,19 @@ public function contains($dql): bool */ public function setFirstResult($firstResult): self { - $this->firstResult = (int) $firstResult; + if (! is_int($firstResult)) { + Deprecation::trigger( + 'doctrine/orm', + 'https://github.com/doctrine/orm/pull/9809', + 'Calling %s with %s is deprecated and will result in a TypeError in Doctrine 3.0. Pass an integer.', + __METHOD__, + get_debug_type($firstResult) + ); + + $firstResult = (int) $firstResult; + } + + $this->firstResult = $firstResult; $this->_state = self::STATE_DIRTY; return $this; diff --git a/lib/Doctrine/ORM/Query/Exec/MultiTableDeleteExecutor.php b/lib/Doctrine/ORM/Query/Exec/MultiTableDeleteExecutor.php index 99b34cefcce..20586e1b9e3 100644 --- a/lib/Doctrine/ORM/Query/Exec/MultiTableDeleteExecutor.php +++ b/lib/Doctrine/ORM/Query/Exec/MultiTableDeleteExecutor.php @@ -99,7 +99,7 @@ public function __construct(AST\Node $AST, $sqlWalker) } $this->_createTempTableSql = $platform->getCreateTemporaryTableSnippetSQL() . ' ' . $tempTable . ' (' - . $platform->getColumnDeclarationListSQL($columnDefinitions) . ')'; + . $platform->getColumnDeclarationListSQL($columnDefinitions) . ', PRIMARY KEY(' . implode(',', $idColumnNames) . '))'; $this->_dropTempTableSql = $platform->getDropTemporaryTableSQL($tempTable); } diff --git a/lib/Doctrine/ORM/Query/Exec/MultiTableUpdateExecutor.php b/lib/Doctrine/ORM/Query/Exec/MultiTableUpdateExecutor.php index 31e6b4ebe15..8ee3febd901 100644 --- a/lib/Doctrine/ORM/Query/Exec/MultiTableUpdateExecutor.php +++ b/lib/Doctrine/ORM/Query/Exec/MultiTableUpdateExecutor.php @@ -140,7 +140,7 @@ public function __construct(AST\Node $AST, $sqlWalker) } $this->_createTempTableSql = $platform->getCreateTemporaryTableSnippetSQL() . ' ' . $tempTable . ' (' - . $platform->getColumnDeclarationListSQL($columnDefinitions) . ')'; + . $platform->getColumnDeclarationListSQL($columnDefinitions) . ', PRIMARY KEY(' . implode(',', $idColumnNames) . '))'; $this->_dropTempTableSql = $platform->getDropTemporaryTableSQL($tempTable); } diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index 51bef411acb..2cff0b45469 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -26,6 +26,7 @@ use Doctrine\ORM\Internal\CommitOrderCalculator; use Doctrine\ORM\Internal\HydrationCompleteHandler; use Doctrine\ORM\Mapping\ClassMetadata; +use Doctrine\ORM\Mapping\ClassMetadataInfo; use Doctrine\ORM\Mapping\MappingException; use Doctrine\ORM\Persisters\Collection\CollectionPersister; use Doctrine\ORM\Persisters\Collection\ManyToManyPersister; @@ -71,6 +72,8 @@ * in the correct order. * * Internal note: This class contains highly performance-sensitive code. + * + * @psalm-import-type AssociationMapping from ClassMetadataInfo */ class UnitOfWork implements PropertyChangedListener { diff --git a/psalm-baseline.xml b/psalm-baseline.xml index fdb772aef3c..a142a56e010 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -55,6 +55,16 @@ $em->getMetadataFactory() + + $targetClassMetadata->associationMappings + + + $assoc['fetch'] + $assoc['isOwningSide'] + $assoc['isOwningSide'] + $assoc['joinColumnFieldNames'] + $assoc['mappedBy'] + getCacheRegion @@ -142,6 +152,10 @@ getCacheFactory getTimestampRegion + + $assoc['fetch'] + $assoc['isOwningSide'] + assert($metadata instanceof ClassMetadata) @@ -251,6 +265,10 @@ + + $class->associationMappings[$fieldName]['joinColumns'] + $class->associationMappings[$fieldName]['joinColumns'] + return $rowData; @@ -283,9 +301,13 @@ $parentObject $parentObject - + $objectClass + $relation['mappedBy'] + + $targetClass->reflFields + getValue getValue @@ -294,8 +316,16 @@ setValue setValue - + + $assoc['inversedBy'] + $assoc['mappedBy'] + $class->associationMappings[$class->identifier[0]]['joinColumns'] + $class->associationMappings[$fieldName]['joinColumns'] $newObject['args'] + $relation['inversedBy'] + $relation['isOwningSide'] + $relation['mappedBy'] + $relation['mappedBy'] @@ -376,6 +406,9 @@ hasListeners loadMetadataForClass + + $mapping['isOwningSide'] + $parent->generatorType $parent->generatorType @@ -390,8 +423,9 @@ $this->columnNames $this->columnNames - + ! $this->table + ! class_exists($mapping['targetEntity']) $this->table @@ -399,7 +433,7 @@ protected function _validateAndCompleteManyToManyMapping(array $mapping) protected function _validateAndCompleteOneToOneMapping(array $mapping) - + ReflectionProperty ReflectionProperty getReflectionClass @@ -414,9 +448,6 @@ $className $this->namespace . '\\' . $className - - $joinColumn - static function ($joinColumn) { @@ -429,7 +460,7 @@ array{usage: int, region: string|null} class-string|null - + $this->reflClass $this->reflFields[$name] $this->reflFields[$this->identifier[0]] @@ -457,10 +488,15 @@ setValue setValue - + $mapping['originalClass'] $mapping['originalField'] $mapping['targetEntity'] + $this->associationMappings[$assocName]['joinColumns'] + $this->associationMappings[$fieldName]['joinColumns'] + $this->associationMappings[$fieldName]['joinColumns'] + $this->associationMappings[$idProperty]['joinColumns'] + $this->associationMappings[$idProperty]['joinColumns'] $idGenerator @@ -468,7 +504,9 @@ $sequenceGeneratorDefinition $table - + + $this->associationMappings + $this->associationMappings $this->discriminatorMap $this->entityListeners $this->fieldMappings @@ -514,9 +552,9 @@ - - $joinColumn - + + $class->associationMappings[$fieldName]['joinColumns'] + @@ -762,6 +800,11 @@ $entity + + + MemcachedAdapter::createConnection('memcached://127.0.0.1') + + isset($offset) @@ -925,6 +968,9 @@ getFieldForColumn getFieldForColumn + + $mapping['joinTable'] + @@ -969,6 +1015,9 @@ $targetClass->associationMappings + + $targetClass->associationMappings[$mapping['mappedBy']]['joinColumns'] + @@ -994,13 +1043,18 @@ array array - + + $assoc['mappedBy'] $association $type $assoc['isOwningSide'] + + $class->associationMappings + $class->associationMappings + getValue getValue @@ -1010,6 +1064,37 @@ getValue setValue + + $assoc['fetch'] + $assoc['isOwningSide'] + $assoc['isOwningSide'] + $assoc['isOwningSide'] + $assoc['isOwningSide'] + $assoc['isOwningSide'] + $assoc['joinColumns'] + $assoc['joinColumns'] + $assoc['mappedBy'] + $assoc['mappedBy'] + $assoc['relationToTargetKeyColumns'] + $assoc['sourceToTargetKeyColumns'] + $association['isOwningSide'] + $association['isOwningSide'] + $association['joinColumns'] + $association['joinColumns'] + $association['joinColumns'] + $association['joinTable'] + $association['joinTable'] + $association['joinTable'] + $association['joinTable'] + $association['sourceEntity'] + $association['sourceEntity'] + $mapping['isOwningSide'] + $mapping['mappedBy'] + $mapping['sourceEntity'] + $this->class->associationMappings[$fieldName]['isOwningSide'] + $this->class->associationMappings[$fieldName]['joinColumns'] + $this->class->associationMappings[$idField]['joinColumns'] + $this->currentPersisterContext->sqlTableAliases @@ -1032,8 +1117,19 @@ array + + $assoc['isOwningSide'] + $mapping['isOwningSide'] + $mapping['isOwningSide'] + $mapping['joinColumns'] + $mapping['joinColumns'] + + + $assoc['isOwningSide'] + $assoc['joinColumns'] + $columnList @@ -1089,9 +1185,6 @@ $parserResult - - $timeToLive !== null - @@ -1265,6 +1358,10 @@ $parser->getLexer()->token['value'] + + $assoc['joinColumns'] + $assoc['sourceEntity'] + $pathExpression @@ -1318,6 +1415,16 @@ + + $targetClass->associationMappings + $targetClass->associationMappings + + + $assoc['isOwningSide'] + $assoc['mappedBy'] + $assoc['mappedBy'] + $owningAssoc['joinTable'] + $collectionPathExpression @@ -1900,6 +2007,9 @@ getNumberOfRequiredParameters + + $class->associationMappings[$field]['isOwningSide'] + $args @@ -1919,6 +2029,16 @@ Comparison::EQ + + + $associationMapping['isOwningSide'] + $associationMapping['isOwningSide'] + $associationMapping['isOwningSide'] + $associationMapping['joinColumns'] + $associationMapping['joinColumns'] + $associationMapping['joinColumns'] + + '' @@ -2006,13 +2126,30 @@ $identificationVariableDecl->rangeVariableDeclaration $subselect->whereClause - + + $targetClass->associationMappings + $targetClass->associationMappings $this->scalarResultAliasMap $this->scalarResultAliasMap dispatch + + $assoc['isOwningSide'] + $assoc['isOwningSide'] + $assoc['isOwningSide'] + $assoc['isOwningSide'] + $assoc['joinColumns'] + $assoc['joinColumns'] + $assoc['mappedBy'] + $assoc['mappedBy'] + $assoc['sourceToTargetKeyColumns'] + $association['isOwningSide'] + $association['sourceToTargetKeyColumns'] + $mapping['isOwningSide'] + $owningAssoc['joinTable'] + $whereClause !== null ($factor->not ? 'NOT ' : '') . $this->walkConditionalPrimary($factor->conditionalPrimary) @@ -2143,6 +2280,9 @@ $query + + $rootClass->associationMappings[$property]['joinColumns'] + @@ -2162,6 +2302,9 @@ $orderByClause->orderByItems + + $rootClass->associationMappings[$property]['joinColumns'] + @@ -2205,9 +2348,17 @@ getColumns - + + $assoc['joinColumns'] + $class->getAssociationMapping($fieldName)['joinColumns'] $fieldMapping['precision'] $fieldMapping['scale'] + $idMapping['joinColumns'] + $mapping['isOwningSide'] + $mapping['isOwningSide'] + $mapping['isOwningSide'] + $mapping['joinColumns'] + $mapping['joinTable'] is_numeric($indexName) @@ -2220,6 +2371,29 @@ $indexName + + + ! class_exists($assoc['targetEntity']) + + + $assoc['inversedBy'] + $assoc['inversedBy'] + $assoc['isOwningSide'] + $assoc['joinColumns'] + $assoc['joinTable'] + $assoc['mappedBy'] + $assoc['relationToSourceKeyColumns'] + $assoc['relationToTargetKeyColumns'] + $targetMetadata->associationMappings[$assoc['inversedBy']]['mappedBy'] + $targetMetadata->associationMappings[$assoc['inversedBy']]['mappedBy'] + $targetMetadata->associationMappings[$assoc['mappedBy']]['inversedBy'] + $targetMetadata->associationMappings[$assoc['mappedBy']]['inversedBy'] + + + $assoc['orderBy'] !== null + isset($assoc['orderBy']) && $assoc['orderBy'] !== null + + $class @@ -2238,12 +2412,6 @@ $this->entityChangeSets $this->entityChangeSets - - static function (array $assoc) { - static function (array $assoc) { - static function (array $assoc) { - static function (array $assoc) { - $this->identityMap[$rootClassName][$idHash] @@ -2251,6 +2419,8 @@ $this->identityMap[$rootClassName] + $assoc + $assoc $assoc $assoc $assoc['targetEntity'] @@ -2265,6 +2435,9 @@ $assoc['targetEntity'] $assoc['type'] + + $targetClass->reflFields + buildCachedCollectionPersister buildCachedEntityPersister @@ -2294,6 +2467,23 @@ setValue setValue + + $assoc['fetch'] + $assoc['fetch'] + $assoc['inversedBy'] + $assoc['isCascadeDetach'] + $assoc['isCascadePersist'] + $assoc['isCascadeRefresh'] + $assoc['isCascadeRemove'] + $assoc['isOwningSide'] + $assoc['isOwningSide'] + $assoc['isOwningSide'] + $assoc['isOwningSide'] + $assoc['isOwningSide'] + $assoc['joinColumns'] + $assoc['mappedBy'] + $assoc['orphanRemoval'] + addPropertyChangedListener unwrap @@ -2315,4 +2505,19 @@ $rootClassMetadata->subClasses + + + $class->associationMappings[$field]['joinColumns'] + + + + + $assoc['mappedBy'] + + + $assoc['isOwningSide'] + $assoc['joinTable'] + $assoc['mappedBy'] + + diff --git a/tests/Doctrine/Tests/ORM/Cache/DefaultRegionTest.php b/tests/Doctrine/Tests/ORM/Cache/DefaultRegionTest.php index d8a3eefd838..800ee240ad4 100644 --- a/tests/Doctrine/Tests/ORM/Cache/DefaultRegionTest.php +++ b/tests/Doctrine/Tests/ORM/Cache/DefaultRegionTest.php @@ -12,10 +12,10 @@ use function array_map; /** - * @extends AbstractRegionTest + * @extends RegionTestCase * @group DDC-2183 */ -class DefaultRegionTest extends AbstractRegionTest +class DefaultRegionTest extends RegionTestCase { protected function createRegion(): DefaultRegion { diff --git a/tests/Doctrine/Tests/ORM/Cache/FileLockRegionTest.php b/tests/Doctrine/Tests/ORM/Cache/FileLockRegionTest.php index 9dc2b687e10..06c51cb9d38 100644 --- a/tests/Doctrine/Tests/ORM/Cache/FileLockRegionTest.php +++ b/tests/Doctrine/Tests/ORM/Cache/FileLockRegionTest.php @@ -28,11 +28,11 @@ use const E_WARNING; /** - * @extends AbstractRegionTest + * @extends RegionTestCase * @group DDC-2183 * @extends AbstractRegionTest */ -class FileLockRegionTest extends AbstractRegionTest +class FileLockRegionTest extends RegionTestCase { protected string $directory; diff --git a/tests/Doctrine/Tests/ORM/Cache/Persister/Collection/AbstractCollectionPersisterTest.php b/tests/Doctrine/Tests/ORM/Cache/Persister/Collection/CollectionPersisterTestCase.php similarity index 99% rename from tests/Doctrine/Tests/ORM/Cache/Persister/Collection/AbstractCollectionPersisterTest.php rename to tests/Doctrine/Tests/ORM/Cache/Persister/Collection/CollectionPersisterTestCase.php index 07acaf71427..19c0c1c3ff0 100644 --- a/tests/Doctrine/Tests/ORM/Cache/Persister/Collection/AbstractCollectionPersisterTest.php +++ b/tests/Doctrine/Tests/ORM/Cache/Persister/Collection/CollectionPersisterTestCase.php @@ -20,7 +20,7 @@ /** * @group DDC-2183 */ -abstract class AbstractCollectionPersisterTest extends OrmTestCase +abstract class CollectionPersisterTestCase extends OrmTestCase { /** @var Region&MockObject */ protected Region $region; diff --git a/tests/Doctrine/Tests/ORM/Cache/Persister/Collection/NonStrictReadWriteCachedCollectionPersisterTest.php b/tests/Doctrine/Tests/ORM/Cache/Persister/Collection/NonStrictReadWriteCachedCollectionPersisterTest.php index 7c3a369d026..60daa7a9156 100644 --- a/tests/Doctrine/Tests/ORM/Cache/Persister/Collection/NonStrictReadWriteCachedCollectionPersisterTest.php +++ b/tests/Doctrine/Tests/ORM/Cache/Persister/Collection/NonStrictReadWriteCachedCollectionPersisterTest.php @@ -13,7 +13,7 @@ /** * @group DDC-2183 */ -class NonStrictReadWriteCachedCollectionPersisterTest extends AbstractCollectionPersisterTest +class NonStrictReadWriteCachedCollectionPersisterTest extends CollectionPersisterTestCase { protected function createPersister(EntityManagerInterface $em, CollectionPersister $persister, Region $region, array $mapping): AbstractCollectionPersister { diff --git a/tests/Doctrine/Tests/ORM/Cache/Persister/Collection/ReadOnlyCachedCollectionPersisterTest.php b/tests/Doctrine/Tests/ORM/Cache/Persister/Collection/ReadOnlyCachedCollectionPersisterTest.php index 9dbbb2a5f76..ef8ce486d08 100644 --- a/tests/Doctrine/Tests/ORM/Cache/Persister/Collection/ReadOnlyCachedCollectionPersisterTest.php +++ b/tests/Doctrine/Tests/ORM/Cache/Persister/Collection/ReadOnlyCachedCollectionPersisterTest.php @@ -13,7 +13,7 @@ /** * @group DDC-2183 */ -class ReadOnlyCachedCollectionPersisterTest extends AbstractCollectionPersisterTest +class ReadOnlyCachedCollectionPersisterTest extends CollectionPersisterTestCase { protected function createPersister(EntityManagerInterface $em, CollectionPersister $persister, Region $region, array $mapping): AbstractCollectionPersister { diff --git a/tests/Doctrine/Tests/ORM/Cache/Persister/Collection/ReadWriteCachedCollectionPersisterTest.php b/tests/Doctrine/Tests/ORM/Cache/Persister/Collection/ReadWriteCachedCollectionPersisterTest.php index 104c208fe5b..cbc9c0b509d 100644 --- a/tests/Doctrine/Tests/ORM/Cache/Persister/Collection/ReadWriteCachedCollectionPersisterTest.php +++ b/tests/Doctrine/Tests/ORM/Cache/Persister/Collection/ReadWriteCachedCollectionPersisterTest.php @@ -19,7 +19,7 @@ /** * @group DDC-2183 */ -class ReadWriteCachedCollectionPersisterTest extends AbstractCollectionPersisterTest +class ReadWriteCachedCollectionPersisterTest extends CollectionPersisterTestCase { protected function createPersister(EntityManagerInterface $em, CollectionPersister $persister, Region $region, array $mapping): AbstractCollectionPersister { diff --git a/tests/Doctrine/Tests/ORM/Cache/Persister/Entity/AbstractEntityPersisterTest.php b/tests/Doctrine/Tests/ORM/Cache/Persister/Entity/EntityPersisterTestCase.php similarity index 99% rename from tests/Doctrine/Tests/ORM/Cache/Persister/Entity/AbstractEntityPersisterTest.php rename to tests/Doctrine/Tests/ORM/Cache/Persister/Entity/EntityPersisterTestCase.php index a1c32640dd3..ae3d7655a57 100644 --- a/tests/Doctrine/Tests/ORM/Cache/Persister/Entity/AbstractEntityPersisterTest.php +++ b/tests/Doctrine/Tests/ORM/Cache/Persister/Entity/EntityPersisterTestCase.php @@ -23,7 +23,7 @@ /** * @group DDC-2183 */ -abstract class AbstractEntityPersisterTest extends OrmTestCase +abstract class EntityPersisterTestCase extends OrmTestCase { /** @var Region&MockObject */ protected Region $region; diff --git a/tests/Doctrine/Tests/ORM/Cache/Persister/Entity/NonStrictReadWriteCachedEntityPersisterTest.php b/tests/Doctrine/Tests/ORM/Cache/Persister/Entity/NonStrictReadWriteCachedEntityPersisterTest.php index 46f6a9b4fdc..61b40c2b17a 100644 --- a/tests/Doctrine/Tests/ORM/Cache/Persister/Entity/NonStrictReadWriteCachedEntityPersisterTest.php +++ b/tests/Doctrine/Tests/ORM/Cache/Persister/Entity/NonStrictReadWriteCachedEntityPersisterTest.php @@ -18,7 +18,7 @@ /** * @group DDC-2183 */ -class NonStrictReadWriteCachedEntityPersisterTest extends AbstractEntityPersisterTest +class NonStrictReadWriteCachedEntityPersisterTest extends EntityPersisterTestCase { protected function createPersister(EntityManagerInterface $em, EntityPersister $persister, Region $region, ClassMetadata $metadata): AbstractEntityPersister { diff --git a/tests/Doctrine/Tests/ORM/Cache/Persister/Entity/ReadOnlyCachedEntityPersisterTest.php b/tests/Doctrine/Tests/ORM/Cache/Persister/Entity/ReadOnlyCachedEntityPersisterTest.php index e8214f18afd..7fba7a82417 100644 --- a/tests/Doctrine/Tests/ORM/Cache/Persister/Entity/ReadOnlyCachedEntityPersisterTest.php +++ b/tests/Doctrine/Tests/ORM/Cache/Persister/Entity/ReadOnlyCachedEntityPersisterTest.php @@ -16,7 +16,7 @@ /** * @group DDC-2183 */ -class ReadOnlyCachedEntityPersisterTest extends AbstractEntityPersisterTest +class ReadOnlyCachedEntityPersisterTest extends EntityPersisterTestCase { protected function createPersister(EntityManagerInterface $em, EntityPersister $persister, Region $region, ClassMetadata $metadata): AbstractEntityPersister { diff --git a/tests/Doctrine/Tests/ORM/Cache/Persister/Entity/ReadWriteCachedEntityPersisterTest.php b/tests/Doctrine/Tests/ORM/Cache/Persister/Entity/ReadWriteCachedEntityPersisterTest.php index 11996e6855b..7bc17860d5a 100644 --- a/tests/Doctrine/Tests/ORM/Cache/Persister/Entity/ReadWriteCachedEntityPersisterTest.php +++ b/tests/Doctrine/Tests/ORM/Cache/Persister/Entity/ReadWriteCachedEntityPersisterTest.php @@ -19,7 +19,7 @@ /** * @group DDC-2183 */ -class ReadWriteCachedEntityPersisterTest extends AbstractEntityPersisterTest +class ReadWriteCachedEntityPersisterTest extends EntityPersisterTestCase { protected function createPersister(EntityManagerInterface $em, EntityPersister $persister, Region $region, ClassMetadata $metadata): AbstractEntityPersister { diff --git a/tests/Doctrine/Tests/ORM/Cache/AbstractRegionTest.php b/tests/Doctrine/Tests/ORM/Cache/RegionTestCase.php similarity index 97% rename from tests/Doctrine/Tests/ORM/Cache/AbstractRegionTest.php rename to tests/Doctrine/Tests/ORM/Cache/RegionTestCase.php index 5648b3b70a6..fcbc6d1d2eb 100644 --- a/tests/Doctrine/Tests/ORM/Cache/AbstractRegionTest.php +++ b/tests/Doctrine/Tests/ORM/Cache/RegionTestCase.php @@ -17,7 +17,7 @@ * @template TRegion of Region * @group DDC-2183 */ -abstract class AbstractRegionTest extends OrmFunctionalTestCase +abstract class RegionTestCase extends OrmFunctionalTestCase { /** @psalm-var TRegion */ protected Region $region; diff --git a/tests/Doctrine/Tests/ORM/Functional/QueryCacheTest.php b/tests/Doctrine/Tests/ORM/Functional/QueryCacheTest.php index 4d19ce9a126..3c12c89c589 100644 --- a/tests/Doctrine/Tests/ORM/Functional/QueryCacheTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/QueryCacheTest.php @@ -128,19 +128,14 @@ public function testQueryCacheHitDoesNotSaveParserResult(): void $query = $this->_em->createQuery('select ux from Doctrine\Tests\Models\CMS\CmsUser ux'); $sqlExecMock = $this->getMockBuilder(AbstractSqlExecutor::class) - ->setMethods(['execute']) - ->getMock(); + ->getMockForAbstractClass(); $sqlExecMock->expects(self::once()) ->method('execute') ->willReturn(10); - $parserResultMock = $this->getMockBuilder(ParserResult::class) - ->setMethods(['getSqlExecutor']) - ->getMock(); - $parserResultMock->expects(self::once()) - ->method('getSqlExecutor') - ->willReturn($sqlExecMock); + $parserResultMock = new ParserResult(); + $parserResultMock->setSqlExecutor($sqlExecMock); $cache = $this->createMock(CacheItemPoolInterface::class); diff --git a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheCompositePrimaryKeyTest.php b/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheCompositePrimaryKeyTest.php index 28ab138ac7c..555f6ca991d 100644 --- a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheCompositePrimaryKeyTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheCompositePrimaryKeyTest.php @@ -11,7 +11,7 @@ /** * @group DDC-2183 */ -class SecondLevelCacheCompositePrimaryKeyTest extends SecondLevelCacheAbstractTest +class SecondLevelCacheCompositePrimaryKeyTest extends SecondLevelCacheFunctionalTestCase { public function testPutAndLoadCompositPrimaryKeyEntities(): void { diff --git a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheConcurrentTest.php b/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheConcurrentTest.php index dd0291f61ff..1d3659d39eb 100644 --- a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheConcurrentTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheConcurrentTest.php @@ -21,7 +21,7 @@ /** * @group DDC-2183 */ -class SecondLevelCacheConcurrentTest extends SecondLevelCacheAbstractTest +class SecondLevelCacheConcurrentTest extends SecondLevelCacheFunctionalTestCase { private CacheFactorySecondLevelCacheConcurrentTest $cacheFactory; private ClassMetadata $countryMetadata; diff --git a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheCriteriaTest.php b/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheCriteriaTest.php index d4ddcb53664..f77e50e085e 100644 --- a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheCriteriaTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheCriteriaTest.php @@ -12,7 +12,7 @@ /** * @group DDC-2183 */ -class SecondLevelCacheCriteriaTest extends SecondLevelCacheAbstractTest +class SecondLevelCacheCriteriaTest extends SecondLevelCacheFunctionalTestCase { public function testMatchingPut(): void { diff --git a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheExtraLazyCollectionTest.php b/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheExtraLazyCollectionTest.php index 1165153aded..3dc1039dc6e 100644 --- a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheExtraLazyCollectionTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheExtraLazyCollectionTest.php @@ -12,7 +12,7 @@ /** * @group DDC-2183 */ -class SecondLevelCacheExtraLazyCollectionTest extends SecondLevelCacheAbstractTest +class SecondLevelCacheExtraLazyCollectionTest extends SecondLevelCacheFunctionalTestCase { protected function setUp(): void { diff --git a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheAbstractTest.php b/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheFunctionalTestCase.php similarity index 99% rename from tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheAbstractTest.php rename to tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheFunctionalTestCase.php index 3ef5a3c2064..f09e4d0a4bc 100644 --- a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheAbstractTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheFunctionalTestCase.php @@ -26,7 +26,7 @@ /** * @group DDC-2183 */ -abstract class SecondLevelCacheAbstractTest extends OrmFunctionalTestCase +abstract class SecondLevelCacheFunctionalTestCase extends OrmFunctionalTestCase { /** @psalm-var list */ protected array $people = []; diff --git a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheJoinTableInheritanceTest.php b/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheJoinTableInheritanceTest.php index ff6b06bf268..4dfb1c4b2f2 100644 --- a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheJoinTableInheritanceTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheJoinTableInheritanceTest.php @@ -15,7 +15,7 @@ /** * @group DDC-2183 */ -class SecondLevelCacheJoinTableInheritanceTest extends SecondLevelCacheAbstractTest +class SecondLevelCacheJoinTableInheritanceTest extends SecondLevelCacheFunctionalTestCase { public function testUseSameRegion(): void { diff --git a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheManyToManyTest.php b/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheManyToManyTest.php index 5ea87f46e5f..2177f90047a 100644 --- a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheManyToManyTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheManyToManyTest.php @@ -13,7 +13,7 @@ /** * @group DDC-2183 */ -class SecondLevelCacheManyToManyTest extends SecondLevelCacheAbstractTest +class SecondLevelCacheManyToManyTest extends SecondLevelCacheFunctionalTestCase { public function testShouldPutManyToManyCollectionOwningSideOnPersist(): void { diff --git a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheManyToOneTest.php b/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheManyToOneTest.php index 455dc8e03b0..0a480b55609 100644 --- a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheManyToOneTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheManyToOneTest.php @@ -15,7 +15,7 @@ /** * @group DDC-2183 */ -class SecondLevelCacheManyToOneTest extends SecondLevelCacheAbstractTest +class SecondLevelCacheManyToOneTest extends SecondLevelCacheFunctionalTestCase { public function testPutOnPersist(): void { diff --git a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheOneToManyTest.php b/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheOneToManyTest.php index 72e325aeb13..6cdfce8af94 100644 --- a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheOneToManyTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheOneToManyTest.php @@ -17,7 +17,7 @@ /** * @group DDC-2183 */ -class SecondLevelCacheOneToManyTest extends SecondLevelCacheAbstractTest +class SecondLevelCacheOneToManyTest extends SecondLevelCacheFunctionalTestCase { public function testShouldPutCollectionInverseSideOnPersist(): void { diff --git a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheOneToOneTest.php b/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheOneToOneTest.php index defc6828bf7..776f3b1f66d 100644 --- a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheOneToOneTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheOneToOneTest.php @@ -16,7 +16,7 @@ /** * @group DDC-2183 */ -class SecondLevelCacheOneToOneTest extends SecondLevelCacheAbstractTest +class SecondLevelCacheOneToOneTest extends SecondLevelCacheFunctionalTestCase { public function testPutOneToOneOnUnidirectionalPersist(): void { diff --git a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheQueryCacheTest.php b/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheQueryCacheTest.php index 47a0e8567c3..adddc8b92e3 100644 --- a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheQueryCacheTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheQueryCacheTest.php @@ -23,7 +23,7 @@ /** * @group DDC-2183 */ -class SecondLevelCacheQueryCacheTest extends SecondLevelCacheAbstractTest +class SecondLevelCacheQueryCacheTest extends SecondLevelCacheFunctionalTestCase { public function testBasicQueryCache(): void { diff --git a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheRepositoryTest.php b/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheRepositoryTest.php index 21907e55d66..25cab2d372c 100644 --- a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheRepositoryTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheRepositoryTest.php @@ -11,7 +11,7 @@ /** * @group DDC-2183 */ -class SecondLevelCacheRepositoryTest extends SecondLevelCacheAbstractTest +class SecondLevelCacheRepositoryTest extends SecondLevelCacheFunctionalTestCase { public function testRepositoryCacheFind(): void { diff --git a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheSingleTableInheritanceTest.php b/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheSingleTableInheritanceTest.php index 5c10b4478bb..76e3547d870 100644 --- a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheSingleTableInheritanceTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheSingleTableInheritanceTest.php @@ -16,7 +16,7 @@ /** * @group DDC-2183 */ -class SecondLevelCacheSingleTableInheritanceTest extends SecondLevelCacheAbstractTest +class SecondLevelCacheSingleTableInheritanceTest extends SecondLevelCacheFunctionalTestCase { public function testUseSameRegion(): void { diff --git a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheTest.php b/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheTest.php index 50aa74c0f5e..5d2fd050358 100644 --- a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheTest.php @@ -18,7 +18,7 @@ /** * @group DDC-2183 */ -class SecondLevelCacheTest extends SecondLevelCacheAbstractTest +class SecondLevelCacheTest extends SecondLevelCacheFunctionalTestCase { public function testPutOnPersist(): void { diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2359Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2359Test.php index 32af0bbf530..393ca3c7df9 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2359Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2359Test.php @@ -15,16 +15,16 @@ use Doctrine\ORM\Mapping\GeneratedValue; use Doctrine\ORM\Mapping\Id; use Doctrine\Persistence\Mapping\Driver\MappingDriver; -use PHPUnit\Framework\MockObject\MockObject; +use Doctrine\Tests\PHPUnitCompatibility\MockBuilderCompatibilityTools; use PHPUnit\Framework\TestCase; -use function assert; - /** * @group DDC-2359 */ class DDC2359Test extends TestCase { + use MockBuilderCompatibilityTools; + /** * Verifies that {@see \Doctrine\ORM\Mapping\ClassMetadataFactory::wakeupReflection} is * not called twice when loading metadata from a driver @@ -35,14 +35,13 @@ public function testIssue(): void $mockMetadata = $this->createMock(ClassMetadata::class); $entityManager = $this->createMock(EntityManager::class); - $metadataFactory = $this->getMockBuilder(ClassMetadataFactory::class) - ->setMethods(['newClassMetadataInstance', 'wakeupReflection']) - ->getMock(); - assert($metadataFactory instanceof ClassMetadataFactory || $metadataFactory instanceof MockObject); + $metadataFactory = $this + ->getMockBuilderWithOnlyMethods(ClassMetadataFactory::class, ['newClassMetadataInstance', 'wakeupReflection']) + ->getMock(); - $configuration = $this->getMockBuilder(Configuration::class) - ->setMethods(['getMetadataDriverImpl']) - ->getMock(); + $configuration = $this + ->getMockBuilderWithOnlyMethods(Configuration::class, ['getMetadataDriverImpl']) + ->getMock(); $connection = $this->createMock(Connection::class); diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2692Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2692Test.php index 2b917fe12e6..ff789d9c88c 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2692Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2692Test.php @@ -39,11 +39,24 @@ protected function setUp(): void public function testIsListenerCalledOnlyOnceOnPreFlush(): void { - $listener = $this->getMockBuilder(DDC2692Listener::class) - ->setMethods(['preFlush']) - ->getMock(); + $listener = new class implements EventSubscriber + { + /** @var int */ + public $registeredCalls = 0; - $listener->expects(self::once())->method('preFlush'); + /** + * {@inheritDoc} + */ + public function getSubscribedEvents(): array + { + return [Events::preFlush]; + } + + public function preFlush(PreFlushEventArgs $args): void + { + ++$this->registeredCalls; + } + }; $this->_em->getEventManager()->addEventSubscriber($listener); @@ -52,6 +65,8 @@ public function testIsListenerCalledOnlyOnceOnPreFlush(): void $this->_em->flush(); $this->_em->clear(); + + self::assertSame(1, $listener->registeredCalls); } } /** @@ -68,18 +83,3 @@ class DDC2692Foo */ public $id; } - -class DDC2692Listener implements EventSubscriber -{ - /** - * {@inheritDoc} - */ - public function getSubscribedEvents(): array - { - return [Events::preFlush]; - } - - public function preFlush(PreFlushEventArgs $args): void - { - } -} diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3123Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3123Test.php index d9eb0ec223b..29ff6eb818c 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3123Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3123Test.php @@ -5,10 +5,11 @@ namespace Doctrine\Tests\ORM\Functional\Ticket; use Doctrine\ORM\Events; +use Doctrine\ORM\UnitOfWork; use Doctrine\Tests\Models\CMS\CmsUser; use Doctrine\Tests\OrmFunctionalTestCase; -use ReflectionObject; -use stdClass; +use PHPUnit\Framework\Assert; +use ReflectionProperty; /** * @group DDC-3123 @@ -32,25 +33,26 @@ public function testIssue(): void $this->_em->persist($user); $uow->scheduleExtraUpdate($user, ['name' => 'changed name']); - $listener = $this->getMockBuilder(stdClass::class) - ->setMethods([Events::postFlush]) - ->getMock(); + $this->_em->getEventManager()->addEventListener(Events::postFlush, new class ($uow) { + /** @var UnitOfWork */ + private $uow; - $listener - ->expects(self::once()) - ->method(Events::postFlush) - ->will(self::returnCallback(function () use ($uow): void { - $reflection = new ReflectionObject($uow); - $property = $reflection->getProperty('extraUpdates'); + public function __construct(UnitOfWork $uow) + { + $this->uow = $uow; + } + public function postFlush(): void + { + $property = new ReflectionProperty(UnitOfWork::class, 'extraUpdates'); $property->setAccessible(true); - $this->assertEmpty( - $property->getValue($uow), + + Assert::assertEmpty( + $property->getValue($this->uow), 'ExtraUpdates are reset before postFlush' ); - })); - - $this->_em->getEventManager()->addEventListener(Events::postFlush, $listener); + } + }); $this->_em->flush(); } diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3967Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3967Test.php index 1a0597bd5d3..e55c93a1f2e 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3967Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3967Test.php @@ -5,12 +5,12 @@ namespace Doctrine\Tests\ORM\Functional\Ticket; use Doctrine\Tests\Models\Cache\Country; -use Doctrine\Tests\ORM\Functional\SecondLevelCacheAbstractTest; +use Doctrine\Tests\ORM\Functional\SecondLevelCacheFunctionalTestCase; use function array_pop; use function assert; -class DDC3967Test extends SecondLevelCacheAbstractTest +class DDC3967Test extends SecondLevelCacheFunctionalTestCase { protected function setUp(): void { diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC4003Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC4003Test.php index 7e6cfe5883b..aea96b6087d 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC4003Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC4003Test.php @@ -5,12 +5,12 @@ namespace Doctrine\Tests\ORM\Functional\Ticket; use Doctrine\Tests\Models\Cache\Bar; -use Doctrine\Tests\ORM\Functional\SecondLevelCacheAbstractTest; +use Doctrine\Tests\ORM\Functional\SecondLevelCacheFunctionalTestCase; use function assert; use function uniqid; -class DDC4003Test extends SecondLevelCacheAbstractTest +class DDC4003Test extends SecondLevelCacheFunctionalTestCase { public function testReadsThroughRepositorySameDataThatItWroteInCache(): void { diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC7969Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC7969Test.php index c09f5c3b5a5..cc6ab7772ce 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC7969Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC7969Test.php @@ -6,11 +6,11 @@ use Doctrine\Tests\Models\Cache\Attraction; use Doctrine\Tests\Models\Cache\Bar; -use Doctrine\Tests\ORM\Functional\SecondLevelCacheAbstractTest; +use Doctrine\Tests\ORM\Functional\SecondLevelCacheFunctionalTestCase; use function assert; -class DDC7969Test extends SecondLevelCacheAbstractTest +class DDC7969Test extends SecondLevelCacheFunctionalTestCase { public function testChildEntityRetrievedFromCache(): void { diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH7869Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH7869Test.php index 0874ef1b4bf..8a60355d7ff 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH7869Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH7869Test.php @@ -32,16 +32,17 @@ public function testDQLDeferredEagerLoad(): void $connection->method('getDatabasePlatform') ->willReturn($platform); - $decoratedEm = EntityManagerMock::create($connection); + $em = new class (EntityManagerMock::create($connection)) extends EntityManagerDecorator { + /** @var int */ + public $getClassMetadataCalls = 0; - $em = $this->getMockBuilder(EntityManagerDecorator::class) - ->setConstructorArgs([$decoratedEm]) - ->setMethods(['getClassMetadata']) - ->getMock(); + public function getClassMetadata($className): ClassMetadata + { + ++$this->getClassMetadataCalls; - $em->expects(self::exactly(2)) - ->method('getClassMetadata') - ->willReturnCallback([$decoratedEm, 'getClassMetadata']); + return parent::getClassMetadata($className); + } + }; $hints = [ UnitOfWork::HINT_DEFEREAGERLOAD => true, @@ -52,6 +53,8 @@ public function testDQLDeferredEagerLoad(): void $uow->createEntity(GH7869Appointment::class, ['id' => 1, 'patient_id' => 1], $hints); $uow->clear(); $uow->triggerEagerLoads(); + + self::assertSame(2, $em->getClassMetadataCalls); } } diff --git a/tests/Doctrine/Tests/ORM/Hydration/AbstractHydratorTest.php b/tests/Doctrine/Tests/ORM/Hydration/AbstractHydratorTest.php index deeee2d0693..1be4b5788d3 100644 --- a/tests/Doctrine/Tests/ORM/Hydration/AbstractHydratorTest.php +++ b/tests/Doctrine/Tests/ORM/Hydration/AbstractHydratorTest.php @@ -61,8 +61,7 @@ protected function setUp(): void $this->hydrator = $this ->getMockBuilder(AbstractHydrator::class) ->setConstructorArgs([$mockEntityManagerInterface]) - ->setMethods(['hydrateAllData']) - ->getMock(); + ->getMockForAbstractClass(); } /** diff --git a/tests/Doctrine/Tests/ORM/Hydration/ObjectHydratorTest.php b/tests/Doctrine/Tests/ORM/Hydration/ObjectHydratorTest.php index 4b39c79a085..c0c74d52b2f 100644 --- a/tests/Doctrine/Tests/ORM/Hydration/ObjectHydratorTest.php +++ b/tests/Doctrine/Tests/ORM/Hydration/ObjectHydratorTest.php @@ -29,11 +29,14 @@ use Doctrine\Tests\Models\Forum\ForumCategory; use Doctrine\Tests\Models\Hydration\EntityWithArrayDefaultArrayValueM2M; use Doctrine\Tests\Models\Hydration\SimpleEntity; +use Doctrine\Tests\PHPUnitCompatibility\MockBuilderCompatibilityTools; use function count; class ObjectHydratorTest extends HydrationTestCase { + use MockBuilderCompatibilityTools; + /** * @psalm-return list */ @@ -1035,8 +1038,7 @@ public function testCreatesProxyForLazyLoadingWithForeignKeys(): void $proxyInstance = new ECommerceShipping(); // mocking the proxy factory - $proxyFactory = $this->getMockBuilder(ProxyFactory::class) - ->setMethods(['getProxy']) + $proxyFactory = $this->getMockBuilderWithOnlyMethods(ProxyFactory::class, ['getProxy']) ->disableOriginalConstructor() ->getMock(); @@ -1084,8 +1086,7 @@ public function testCreatesProxyForLazyLoadingWithForeignKeysWithAliasedProductE $proxyInstance = new ECommerceShipping(); // mocking the proxy factory - $proxyFactory = $this->getMockBuilder(ProxyFactory::class) - ->setMethods(['getProxy']) + $proxyFactory = $this->getMockBuilderWithOnlyMethods(ProxyFactory::class, ['getProxy']) ->disableOriginalConstructor() ->getMock(); diff --git a/tests/Doctrine/Tests/ORM/Id/SequenceGeneratorTest.php b/tests/Doctrine/Tests/ORM/Id/SequenceGeneratorTest.php index d3289678164..2288ebf7ad3 100644 --- a/tests/Doctrine/Tests/ORM/Id/SequenceGeneratorTest.php +++ b/tests/Doctrine/Tests/ORM/Id/SequenceGeneratorTest.php @@ -9,9 +9,12 @@ use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\ORM\Id\SequenceGenerator; use Doctrine\Tests\OrmTestCase; +use Doctrine\Tests\PHPUnitCompatibility\MockBuilderCompatibilityTools; class SequenceGeneratorTest extends OrmTestCase { + use MockBuilderCompatibilityTools; + public function testGeneration(): void { $sequenceGenerator = new SequenceGenerator('seq', 10); @@ -20,9 +23,8 @@ public function testGeneration(): void $platform->method('getSequenceNextValSQL') ->willReturn(''); - $connection = $this->getMockBuilder(Connection::class) + $connection = $this->getMockBuilderWithOnlyMethods(Connection::class, ['fetchOne', 'getDatabasePlatform']) ->setConstructorArgs([[], $this->createMock(Driver::class)]) - ->setMethods(['fetchOne', 'getDatabasePlatform']) ->getMock(); $connection->method('getDatabasePlatform') ->willReturn($platform); diff --git a/tests/Doctrine/Tests/ORM/Mapping/AnnotationDriverTest.php b/tests/Doctrine/Tests/ORM/Mapping/AnnotationDriverTest.php index 9e04a1b6ea8..2a95b15b426 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/AnnotationDriverTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/AnnotationDriverTest.php @@ -37,7 +37,7 @@ use Generator; use stdClass; -class AnnotationDriverTest extends AbstractMappingDriverTest +class AnnotationDriverTest extends MappingDriverTestCase { /** * @group DDC-268 diff --git a/tests/Doctrine/Tests/ORM/Mapping/AttributeDriverTest.php b/tests/Doctrine/Tests/ORM/Mapping/AttributeDriverTest.php index df5d3727fa2..dbed089fb9c 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/AttributeDriverTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/AttributeDriverTest.php @@ -13,7 +13,7 @@ use const PHP_VERSION_ID; -class AttributeDriverTest extends AbstractMappingDriverTest +class AttributeDriverTest extends MappingDriverTestCase { protected function loadDriver(): MappingDriver { diff --git a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataFactoryTest.php b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataFactoryTest.php index bf468fd48de..669e05f6e61 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataFactoryTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataFactoryTest.php @@ -41,11 +41,12 @@ use Doctrine\Tests\Models\Quote\Phone; use Doctrine\Tests\Models\Quote\User; use Doctrine\Tests\OrmTestCase; +use Doctrine\Tests\PHPUnitCompatibility\MockBuilderCompatibilityTools; use DoctrineGlobalArticle; use Exception; use InvalidArgumentException; +use PHPUnit\Framework\Assert; use ReflectionClass; -use stdClass; use function array_search; use function assert; @@ -54,6 +55,7 @@ class ClassMetadataFactoryTest extends OrmTestCase { + use MockBuilderCompatibilityTools; use VerifyDeprecations; public function testGetMetadataForSingleClass(): void @@ -227,15 +229,6 @@ public function testAddDefaultDiscriminatorMap(): void self::assertEquals($childDiscriminatorMap, $rootDiscriminatorMap); self::assertEquals($anotherChildDiscriminatorMap, $rootDiscriminatorMap); - - // ClassMetadataFactory::addDefaultDiscriminatorMap shouldn't be called again, because the - // discriminator map is already cached - $cmf = $this->getMockBuilder(ClassMetadataFactory::class)->setMethods(['addDefaultDiscriminatorMap'])->getMock(); - $cmf->setEntityManager($em); - $cmf->expects(self::never()) - ->method('addDefaultDiscriminatorMap'); - - $rootMetadata = $cmf->getMetadataFor(RootClass::class); } public function testGetAllMetadataWorksWithBadConnection(): void @@ -400,23 +393,31 @@ public function testFallbackLoadingCausesEventTriggeringThatCanModifyFetchedMeta $cmf = new ClassMetadataFactory(); $mockDriver = new MetadataDriverMock(); $em = $this->createEntityManager($mockDriver); - $listener = $this->getMockBuilder(stdClass::class)->setMethods(['onClassMetadataNotFound'])->getMock(); $eventManager = $em->getEventManager(); $cmf->setEntityManager($em); - $listener - ->expects(self::any()) - ->method('onClassMetadataNotFound') - ->will(self::returnCallback(static function (OnClassMetadataNotFoundEventArgs $args) use ($metadata, $em): void { - self::assertNull($args->getFoundMetadata()); - self::assertSame('Foo', $args->getClassName()); - self::assertSame($em, $args->getObjectManager()); - - $args->setFoundMetadata($metadata); - })); - - $eventManager->addEventListener([Events::onClassMetadataNotFound], $listener); + $eventManager->addEventListener([Events::onClassMetadataNotFound], new class ($metadata, $em) { + /** @var ClassMetadata */ + private $metadata; + /** @var EntityManagerInterface */ + private $em; + + public function __construct(ClassMetadata $metadata, EntityManagerInterface $em) + { + $this->metadata = $metadata; + $this->em = $em; + } + + public function onClassMetadataNotFound(OnClassMetadataNotFoundEventArgs $args): void + { + Assert::assertNull($args->getFoundMetadata()); + Assert::assertSame('Foo', $args->getClassName()); + Assert::assertSame($this->em, $args->getObjectManager()); + + $args->setFoundMetadata($this->metadata); + } + }); self::assertSame($metadata, $cmf->getMetadataFor('Foo')); } diff --git a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php b/tests/Doctrine/Tests/ORM/Mapping/MappingDriverTestCase.php similarity index 99% rename from tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php rename to tests/Doctrine/Tests/ORM/Mapping/MappingDriverTestCase.php index 59f732033f7..3c73c12e8a3 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/MappingDriverTestCase.php @@ -77,7 +77,7 @@ use const CASE_UPPER; -abstract class AbstractMappingDriverTest extends OrmTestCase +abstract class MappingDriverTestCase extends OrmTestCase { abstract protected function loadDriver(): MappingDriver; diff --git a/tests/Doctrine/Tests/ORM/Mapping/StaticPHPMappingDriverTest.php b/tests/Doctrine/Tests/ORM/Mapping/StaticPHPMappingDriverTest.php index 7b2660b2fb0..2ebba696dcc 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/StaticPHPMappingDriverTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/StaticPHPMappingDriverTest.php @@ -11,7 +11,7 @@ use const DIRECTORY_SEPARATOR; -class StaticPHPMappingDriverTest extends AbstractMappingDriverTest +class StaticPHPMappingDriverTest extends MappingDriverTestCase { protected function loadDriver(): MappingDriver { diff --git a/tests/Doctrine/Tests/ORM/Mapping/Symfony/AbstractDriverTest.php b/tests/Doctrine/Tests/ORM/Mapping/Symfony/DriverTestCase.php similarity index 98% rename from tests/Doctrine/Tests/ORM/Mapping/Symfony/AbstractDriverTest.php rename to tests/Doctrine/Tests/ORM/Mapping/Symfony/DriverTestCase.php index c6d72cfb7de..8fc417e8fbc 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/Symfony/AbstractDriverTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/Symfony/DriverTestCase.php @@ -19,7 +19,7 @@ /** * @group DDC-1418 */ -abstract class AbstractDriverTest extends TestCase +abstract class DriverTestCase extends TestCase { private string $dir; diff --git a/tests/Doctrine/Tests/ORM/Mapping/Symfony/XmlDriverTest.php b/tests/Doctrine/Tests/ORM/Mapping/Symfony/XmlDriverTest.php index 57d1a8f93cd..7d8ea716792 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/Symfony/XmlDriverTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/Symfony/XmlDriverTest.php @@ -12,7 +12,7 @@ /** * @group DDC-1418 */ -class XmlDriverTest extends AbstractDriverTest +class XmlDriverTest extends DriverTestCase { protected function getFileExtension(): string { diff --git a/tests/Doctrine/Tests/ORM/Mapping/XmlMappingDriverTest.php b/tests/Doctrine/Tests/ORM/Mapping/XmlMappingDriverTest.php index a82eddce744..d8ff285b565 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/XmlMappingDriverTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/XmlMappingDriverTest.php @@ -28,7 +28,7 @@ use const DIRECTORY_SEPARATOR; -class XmlMappingDriverTest extends AbstractMappingDriverTest +class XmlMappingDriverTest extends MappingDriverTestCase { protected function loadDriver(): MappingDriver { diff --git a/tests/Doctrine/Tests/ORM/Proxy/ProxyFactoryTest.php b/tests/Doctrine/Tests/ORM/Proxy/ProxyFactoryTest.php index ed5e202fbfb..f6469ad529f 100644 --- a/tests/Doctrine/Tests/ORM/Proxy/ProxyFactoryTest.php +++ b/tests/Doctrine/Tests/ORM/Proxy/ProxyFactoryTest.php @@ -20,6 +20,7 @@ use Doctrine\Tests\Models\Company\CompanyPerson; use Doctrine\Tests\Models\ECommerce\ECommerceFeature; use Doctrine\Tests\OrmTestCase; +use Doctrine\Tests\PHPUnitCompatibility\MockBuilderCompatibilityTools; use ReflectionProperty; use stdClass; @@ -31,6 +32,8 @@ */ class ProxyFactoryTest extends OrmTestCase { + use MockBuilderCompatibilityTools; + private UnitOfWorkMock $uowMock; private EntityManagerMock $emMock; @@ -57,7 +60,9 @@ public function testReferenceProxyDelegatesLoadingToThePersister(): void { $identifier = ['id' => 42]; $proxyClass = 'Proxies\__CG__\Doctrine\Tests\Models\ECommerce\ECommerceFeature'; - $persister = $this->getMockBuilder(BasicEntityPersister::class)->setMethods(['load'])->disableOriginalConstructor()->getMock(); + $persister = $this->getMockBuilderWithOnlyMethods(BasicEntityPersister::class, ['load']) + ->disableOriginalConstructor() + ->getMock(); $this->uowMock->setEntityPersister(ECommerceFeature::class, $persister); @@ -119,8 +124,7 @@ public function testSkipAbstractClassesOnGeneration(): void public function testFailedProxyLoadingDoesNotMarkTheProxyAsInitialized(): void { $persister = $this - ->getMockBuilder(BasicEntityPersister::class) - ->setMethods(['load', 'getClassMetadata']) + ->getMockBuilderWithOnlyMethods(BasicEntityPersister::class, ['load', 'getClassMetadata']) ->disableOriginalConstructor() ->getMock(); $this->uowMock->setEntityPersister(ECommerceFeature::class, $persister); @@ -150,8 +154,7 @@ public function testFailedProxyLoadingDoesNotMarkTheProxyAsInitialized(): void public function testFailedProxyCloningDoesNotMarkTheProxyAsInitialized(): void { $persister = $this - ->getMockBuilder(BasicEntityPersister::class) - ->setMethods(['load', 'getClassMetadata']) + ->getMockBuilderWithOnlyMethods(BasicEntityPersister::class, ['load', 'getClassMetadata']) ->disableOriginalConstructor() ->getMock(); $this->uowMock->setEntityPersister(ECommerceFeature::class, $persister); @@ -190,8 +193,7 @@ public function testProxyClonesParentFields(): void $classMetaData = $this->emMock->getClassMetadata(CompanyEmployee::class); $persister = $this - ->getMockBuilder(BasicEntityPersister::class) - ->setMethods(['load', 'getClassMetadata']) + ->getMockBuilderWithOnlyMethods(BasicEntityPersister::class, ['load', 'getClassMetadata']) ->disableOriginalConstructor() ->getMock(); $this->uowMock->setEntityPersister(CompanyEmployee::class, $persister); diff --git a/tests/Doctrine/Tests/ORM/Query/ParserResultTest.php b/tests/Doctrine/Tests/ORM/Query/ParserResultTest.php index 506b499d60c..f1bf6ea8e71 100644 --- a/tests/Doctrine/Tests/ORM/Query/ParserResultTest.php +++ b/tests/Doctrine/Tests/ORM/Query/ParserResultTest.php @@ -28,7 +28,7 @@ public function testSetGetSqlExecutor(): void { self::assertNull($this->parserResult->getSqlExecutor()); - $executor = $this->getMockBuilder(AbstractSqlExecutor::class)->setMethods(['execute'])->getMock(); + $executor = $this->getMockForAbstractClass(AbstractSqlExecutor::class); $this->parserResult->setSqlExecutor($executor); self::assertSame($executor, $this->parserResult->getSqlExecutor()); } diff --git a/tests/Doctrine/Tests/ORM/Query/QueryTest.php b/tests/Doctrine/Tests/ORM/Query/QueryTest.php index bf975b5d34c..bedd40bd4f8 100644 --- a/tests/Doctrine/Tests/ORM/Query/QueryTest.php +++ b/tests/Doctrine/Tests/ORM/Query/QueryTest.php @@ -134,6 +134,13 @@ public function testSettingNullDqlIsDeprecated(): void $q->setDQL(null); } + public function testSettingNullFirstResultIsDeprecated(): void + { + $this->expectDeprecationWithIdentifier('https://github.com/doctrine/orm/pull/9809'); + $q = $this->entityManager->createQuery(); + $q->setFirstResult(null); + } + /** * @group DDC-968 */ diff --git a/tests/Doctrine/Tests/ORM/Tools/Pagination/PaginatorTest.php b/tests/Doctrine/Tests/ORM/Tools/Pagination/PaginatorTest.php index 877643a05e9..ea841dfae31 100644 --- a/tests/Doctrine/Tests/ORM/Tools/Pagination/PaginatorTest.php +++ b/tests/Doctrine/Tests/ORM/Tools/Pagination/PaginatorTest.php @@ -14,10 +14,13 @@ use Doctrine\ORM\Query\QueryException; use Doctrine\ORM\Tools\Pagination\Paginator; use Doctrine\Tests\OrmTestCase; +use Doctrine\Tests\PHPUnitCompatibility\MockBuilderCompatibilityTools; use PHPUnit\Framework\MockObject\MockObject; class PaginatorTest extends OrmTestCase { + use MockBuilderCompatibilityTools; + /** @var Connection&MockObject */ private $connection; /** @var EntityManagerInterface&MockObject */ @@ -37,14 +40,12 @@ protected function setUp(): void $driver->method('getDatabasePlatform') ->willReturn($platform); - $this->connection = $this->getMockBuilder(Connection::class) + $this->connection = $this->getMockBuilderWithOnlyMethods(Connection::class, ['executeQuery']) ->setConstructorArgs([[], $driver]) - ->setMethods(['executeQuery']) ->getMock(); - $this->em = $this->getMockBuilder(EntityManagerDecorator::class) + $this->em = $this->getMockBuilderWithOnlyMethods(EntityManagerDecorator::class, ['newHydrator']) ->setConstructorArgs([$this->createTestEntityManagerWithConnection($this->connection)]) - ->setMethods(['newHydrator']) ->getMock(); $this->hydrator = $this->createMock(AbstractHydrator::class); diff --git a/tests/Doctrine/Tests/ORM/UnitOfWorkTest.php b/tests/Doctrine/Tests/ORM/UnitOfWorkTest.php index 1aca9b3c457..e4ab7bd8a60 100644 --- a/tests/Doctrine/Tests/ORM/UnitOfWorkTest.php +++ b/tests/Doctrine/Tests/ORM/UnitOfWorkTest.php @@ -33,6 +33,7 @@ use Doctrine\Tests\Models\Forum\ForumAvatar; use Doctrine\Tests\Models\Forum\ForumUser; use Doctrine\Tests\OrmTestCase; +use Doctrine\Tests\PHPUnitCompatibility\MockBuilderCompatibilityTools; use PHPUnit\Framework\MockObject\MockObject; use stdClass; @@ -45,6 +46,8 @@ */ class UnitOfWorkTest extends OrmTestCase { + use MockBuilderCompatibilityTools; + /** * SUT */ @@ -607,9 +610,8 @@ public function testCommitThrowOptimisticLockExceptionWhenConnectionCommitFails( ->willReturn($platform); // Set another connection mock that fail on commit - $this->connection = $this->getMockBuilder(Connection::class) + $this->connection = $this->getMockBuilderWithOnlyMethods(Connection::class, ['commit']) ->setConstructorArgs([[], $driver]) - ->setMethods(['commit']) ->getMock(); $this->_emMock = EntityManagerMock::create($this->connection, null, $this->eventManager); $this->_unitOfWork = new UnitOfWorkMock($this->_emMock); diff --git a/tests/Doctrine/Tests/PHPUnitCompatibility/MockBuilderCompatibilityTools.php b/tests/Doctrine/Tests/PHPUnitCompatibility/MockBuilderCompatibilityTools.php new file mode 100644 index 00000000000..01cdbe650af --- /dev/null +++ b/tests/Doctrine/Tests/PHPUnitCompatibility/MockBuilderCompatibilityTools.php @@ -0,0 +1,29 @@ + $onlyMethods + * @psalm-param class-string $className + * + * @psalm-return MockBuilder + * + * @template TMockedType of object + */ + private function getMockBuilderWithOnlyMethods(string $className, array $onlyMethods): MockBuilder + { + $builder = $this->getMockBuilder($className); + + return method_exists($builder, 'onlyMethods') + ? $builder->onlyMethods($onlyMethods) // PHPUnit 8+ + : $builder->setMethods($onlyMethods); // PHPUnit 7 + } +}