diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 559f26a..35738bb 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -48,24 +48,14 @@ jobs: ${{ runner.os }}-php-${{ matrix.dependencies }}- ${{ runner.os }}-php- - - name: Install highest dependencies - if: ${{ matrix.dependencies == 'high' }} + - name: Install dependencies run: composer update --no-ansi --no-interaction --no-progress --no-suggest --prefer-dist - - - name: Install lowest dependencies - if: ${{ matrix.dependencies == 'low' }} - run: composer update - --no-ansi - --no-interaction - --no-progress - --no-suggest - --prefer-dist - --prefer-lowest + ${{ matrix.dependencies == 'low' && '--prefer-lowest' || '' }} - name: PHPUnit run: vendor/bin/phpunit diff --git a/README.md b/README.md index 82dc4d3..0390cdd 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,6 @@ The following methods on Doctrine's `EntityManagerInterface` should all work as - find - persist - remove -- merge - flush - getRepository - getCache (will always return `null`) @@ -88,3 +87,10 @@ The following methods are **not** supported at this time: - getFilters - isFiltersStateClean - hasFilters + +## ORM v2 Support + +As of Mocktrine, 1.0 and newer, Doctrine/ORM v3 is the only supported version. +While it was originally a goal to support v2 and v3 in the same major version of Mocktrine, there are too many BC breaks for this to be practical. + +To use Mocktrine to test Doctrine/ORM v2 code, install the 0.x line. diff --git a/composer.json b/composer.json index a212d00..ff0130c 100644 --- a/composer.json +++ b/composer.json @@ -6,7 +6,7 @@ "php": "^8.1", "doctrine/annotations": "^1.10 || ^2.0", "doctrine/collections": "^1.6.8 || ^2.0", - "doctrine/orm": "^2.9", + "doctrine/orm": "^3.0", "doctrine/persistence": "^1.3 || ^2.0 || ^3.0" }, "require-dev": { diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 50ed9d2..992fc29 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -1,10 +1,5 @@ parameters: ignoreErrors: - - - message: "#^Return type \\(Firehed\\\\Mocktrine\\\\InMemoryRepository\\\\) of method Firehed\\\\Mocktrine\\\\InMemoryEntityManager\\:\\:getRepository\\(\\) should be compatible with return type \\(Doctrine\\\\ORM\\\\EntityRepository\\\\) of method Doctrine\\\\ORM\\\\EntityManagerInterface\\:\\:getRepository\\(\\)$#" - count: 1 - path: src/InMemoryEntityManager.php - - message: "#^Property Firehed\\\\Mocktrine\\\\RepositoryContainer\\:\\:\\$values with generic class Firehed\\\\Mocktrine\\\\InMemoryRepository does not specify its types\\: Entity$#" count: 1 diff --git a/src/ArrayALC.php b/src/ArrayALC.php new file mode 100644 index 0000000..e444d8d --- /dev/null +++ b/src/ArrayALC.php @@ -0,0 +1,52 @@ + + * @implements Selectable + * + * @internal + */ +class ArrayALC extends AbstractLazyCollection implements Selectable +{ + /** + * @param Collection $collection + */ + public function __construct( + Collection $collection, + ) { + $this->collection = $collection; + } + + protected function doInitialize(): void + { + // no-op, constructor does this + } + + public function matching(Criteria $criteria) + { + throw new BadMethodCallException('Nested matching not supported'); + } +} diff --git a/src/InMemoryEntityManager.php b/src/InMemoryEntityManager.php index ec18032..ccdc116 100644 --- a/src/InMemoryEntityManager.php +++ b/src/InMemoryEntityManager.php @@ -4,14 +4,17 @@ namespace Firehed\Mocktrine; -use Doctrine\Common\Annotations\AnnotationRegistry; -use Doctrine\Common\Annotations\AnnotationReader; -use Doctrine\Common\Annotations\SimpleAnnotationReader; +use DateTimeInterface; +use Doctrine\DBAL\{ + Connection, + LockMode, +}; use Doctrine\ORM\{ + Cache, Configuration, EntityManagerInterface, + Exception\ORMException, NativeQuery, - ORMException, OptimisticLockException, PessimisticLockException, Query, @@ -19,16 +22,14 @@ Query\ResultSetMapping, UnitOfWork, }; -use Doctrine\ORM\Mapping\{ - Driver\AnnotationDriver, - Driver\DoctrineAnnotations, -}; +use Doctrine\ORM\Mapping\Driver\AttributeDriver; use Doctrine\Persistence\Mapping\{ ClassMetadata, ClassMetadataFactory, Driver\MappingDriver, }; use RuntimeException; +use Throwable; use function class_exists; @@ -95,12 +96,15 @@ public function addOnFlushCallback(callable $callback): void * * @template Entity of object * @param class-string $className - * @param mixed $id The identity of the object to find. * * @return ?Entity The found object. */ - public function find($className, $id) - { + public function find( + string $className, + mixed $id, + LockMode|int|null $lockMode = null, + ?int $lockVersion = null, + ): ?object { return $this->getRepository($className)->find($id); } @@ -111,12 +115,8 @@ public function find($className, $id) * * NOTE: The persist operation always considers objects that are not yet known to * this ObjectManager as NEW. Do not pass detached objects to the persist operation. - * - * @param object $object The instance to make managed and persistent. - * - * @return void */ - public function persist($object) + public function persist(object $object): void { $class = get_class($object); $this->getRepository($class)->manage($object); @@ -127,41 +127,17 @@ public function persist($object) * Removes an object instance. * * A removed object will be removed from the database as a result of the flush operation. - * - * @param object $object The object instance to remove. - * - * @return void */ - public function remove($object) + public function remove(object $object): void { $this->pendingDeletes[get_class($object)][] = $object; } - /** - * Merges the state of a detached object into the persistence context - * of this ObjectManager and returns the managed copy of the object. - * The object passed to merge will not become associated/managed with this ObjectManager. - * - * @param object $object - * - * @return object - */ - public function merge($object) - { - $repo = $this->getRepository(get_class($object)); - $repo->manage($object); - return $object; - } - /** * Clears the ObjectManager. All objects that are currently managed * by this ObjectManager become detached. - * - * @param string|null $objectName if given, only objects of this type will get detached. - * - * @return void */ - public function clear($objectName = null) + public function clear(): void { throw new RuntimeException(__METHOD__ . ' not yet implemented'); } @@ -172,12 +148,8 @@ public function clear($objectName = null) * (including removal of the object), will not be synchronized to the database. * Objects which previously referenced the detached object will continue to * reference it. - * - * @param object $object The object to detach. - * - * @return void */ - public function detach($object) + public function detach(object $object): void { throw new RuntimeException(__METHOD__ . ' not yet implemented'); } @@ -185,12 +157,8 @@ public function detach($object) /** * Refreshes the persistent state of an object from the database, * overriding any local changes that have not yet been persisted. - * - * @param object $object The object to refresh. - * - * @return void */ - public function refresh($object) + public function refresh(object $object, LockMode|int|null $lockMode = null): void { throw new RuntimeException(__METHOD__ . ' not yet implemented'); } @@ -199,10 +167,8 @@ public function refresh($object) * Flushes all changes to objects that have been queued up to now to the database. * This effectively synchronizes the in-memory state of managed objects with the * database. - * - * @return void */ - public function flush() + public function flush(): void { foreach ($this->pendingDeletes as $className => $entities) { $repo = $this->getRepository($className); @@ -244,7 +210,7 @@ public function flush() * @param class-string $className * @return InMemoryRepository */ - public function getRepository($className) + public function getRepository(string $className): InMemoryRepository { if (!$this->repos->has($className)) { $this->repos->set($className, new InMemoryRepository($className, $this->mappingDriver)); @@ -262,9 +228,9 @@ public function getRepository($className) * @template T of object * @param class-string $className * - * @return ClassMetadata + * return ClassMetadata */ - public function getClassMetadata($className) + public function getClassMetadata($className): \Doctrine\ORM\Mapping\ClassMetadata { throw new RuntimeException(__METHOD__ . ' not yet implemented'); } @@ -272,9 +238,9 @@ public function getClassMetadata($className) /** * Gets the metadata factory used to gather the metadata of classes. * - * @return ClassMetadataFactory> + * return ClassMetadataFactory> */ - public function getMetadataFactory() + public function getMetadataFactory(): never { throw new RuntimeException(__METHOD__ . ' not yet implemented'); } @@ -283,24 +249,16 @@ public function getMetadataFactory() * Helper method to initialize a lazy loading proxy or persistent collection. * * This method is a no-op for other objects. - * - * @param object $obj - * - * @return void */ - public function initializeObject($obj) + public function initializeObject(object $obj): void { throw new RuntimeException(__METHOD__ . ' not yet implemented'); } /** * Checks if the object is part of the current UnitOfWork and therefore managed. - * - * @param object $object - * - * @return bool */ - public function contains($object) + public function contains(object $object): bool { throw new RuntimeException(__METHOD__ . ' not yet implemented'); } @@ -309,20 +267,16 @@ public function contains($object) /** * Returns the cache API for managing the second level cache regions or NULL if the cache is not enabled. - * - * @return \Doctrine\ORM\Cache|null */ - public function getCache() + public function getCache(): ?Cache { return null; } /** * Gets the database connection object used by the EntityManager. - * - * @return \Doctrine\DBAL\Connection */ - public function getConnection() + public function getConnection(): Connection { throw new RuntimeException(__METHOD__ . ' not yet implemented'); } @@ -338,59 +292,54 @@ public function getConnection() * $qb->select('u')->from('User', 'u') * ->where($expr->orX($expr->eq('u.id', 1), $expr->eq('u.id', 2))); * - * - * @return \Doctrine\ORM\Query\Expr */ - public function getExpressionBuilder() + public function getExpressionBuilder(): Query\Expr { throw new RuntimeException(__METHOD__ . ' not yet implemented'); } /** * Starts a transaction on the underlying database connection. - * - * @return void */ - public function beginTransaction() + public function beginTransaction(): void { throw new RuntimeException(__METHOD__ . ' not yet implemented'); } /** - * Executes a function in a transaction. - * - * The function gets passed this EntityManager instance as an (optional) parameter. - * - * {@link flush} is invoked prior to transaction commit. - * - * If an exception occurs during execution of the function or flushing or transaction commit, - * the transaction is rolled back, the EntityManager closed and the exception re-thrown. - * - * @param callable $func The function to execute transactionally. - * - * @return mixed The non-empty value returned from the closure or true instead. + * @inheritDoc */ - public function transactional($func) + public function wrapInTransaction(callable $func): mixed { - throw new RuntimeException(__METHOD__ . ' not yet implemented'); + $this->beginTransaction(); + + try { + $return = $func($this); + + $this->flush(); + $this->commit(); + + return $return; + } catch (Throwable $e) { + $this->close(); + $this->rollback(); + + throw $e; + } } /** * Commits a transaction on the underlying database connection. - * - * @return void */ - public function commit() + public function commit(): void { throw new RuntimeException(__METHOD__ . ' not yet implemented'); } /** * Performs a rollback on the underlying database connection. - * - * @return void */ - public function rollback() + public function rollback(): void { throw new RuntimeException(__METHOD__ . ' not yet implemented'); } @@ -399,22 +348,8 @@ public function rollback() * Creates a new Query object. * * @param string $dql The DQL string. - * - * @return Query */ - public function createQuery($dql = '') - { - throw new RuntimeException(__METHOD__ . ' not yet implemented'); - } - - /** - * Creates a Query from a named query. - * - * @param string $name - * - * @return Query - */ - public function createNamedQuery($name) + public function createQuery($dql = ''): Query { throw new RuntimeException(__METHOD__ . ' not yet implemented'); } @@ -424,32 +359,16 @@ public function createNamedQuery($name) * * @param string $sql * @param ResultSetMapping $rsm The ResultSetMapping to use. - * - * @return NativeQuery */ - public function createNativeQuery($sql, ResultSetMapping $rsm) - { - throw new RuntimeException(__METHOD__ . ' not yet implemented'); - } - - /** - * Creates a NativeQuery from a named native query. - * - * @param string $name - * - * @return NativeQuery - */ - public function createNamedNativeQuery($name) + public function createNativeQuery($sql, ResultSetMapping $rsm): NativeQuery { throw new RuntimeException(__METHOD__ . ' not yet implemented'); } /** * Create a QueryBuilder instance - * - * @return QueryBuilder */ - public function createQueryBuilder() + public function createQueryBuilder(): QueryBuilder { throw new RuntimeException(__METHOD__ . ' not yet implemented'); } @@ -458,39 +377,14 @@ public function createQueryBuilder() * Gets a reference to the entity identified by the given type and identifier * without actually loading it, if the entity is not yet loaded. * - * @param string $entityName The name of the entity type. - * @param mixed $id The entity identifier. + * @template T of object + * @param class-string $entityName The name of the entity type. * - * @return object|null The entity reference. + * @return ?T The entity reference. * * @throws ORMException */ - public function getReference($entityName, $id) - { - throw new RuntimeException(__METHOD__ . ' not yet implemented'); - } - - /** - * Gets a partial reference to the entity identified by the given type and identifier - * without actually loading it, if the entity is not yet loaded. - * - * The returned reference may be a partial object if the entity is not yet loaded/managed. - * If it is a partial object it will not initialize the rest of the entity state on access. - * Thus you can only ever safely access the identifier of an entity obtained through - * this method. - * - * The use-cases for partial references involve maintaining bidirectional associations - * without loading one side of the association or to update an entity without loading it. - * Note, however, that in the latter case the original (persistent) entity data will - * never be visible to the application (especially not event listeners) as it will - * never be loaded in the first place. - * - * @param string $entityName The name of the entity type. - * @param mixed $identifier The entity identifier. - * - * @return object|null The (partial) entity reference. - */ - public function getPartialReference($entityName, $identifier) + public function getReference(string $entityName, mixed $id): ?object { throw new RuntimeException(__METHOD__ . ' not yet implemented'); } @@ -499,25 +393,8 @@ public function getPartialReference($entityName, $identifier) * Closes the EntityManager. All entities that are currently managed * by this EntityManager become detached. The EntityManager may no longer * be used after it is closed. - * - * @return void - */ - public function close() - { - throw new RuntimeException(__METHOD__ . ' not yet implemented'); - } - - /** - * Creates a copy of the given entity. Can create a shallow or a deep copy. - * - * @param object $entity The entity to copy. - * @param boolean $deep FALSE for a shallow copy, TRUE for a deep copy. - * - * @return object The new entity. - * - * @throws \BadMethodCallException */ - public function copy($entity, $deep = false) + public function close(): void { throw new RuntimeException(__METHOD__ . ' not yet implemented'); } @@ -525,46 +402,37 @@ public function copy($entity, $deep = false) /** * Acquire a lock on the given entity. * - * @param object $entity - * @param int $lockMode - * @param int|null $lockVersion - * - * @return void - * * @throws OptimisticLockException * @throws PessimisticLockException */ - public function lock($entity, $lockMode, $lockVersion = null) - { + public function lock( + object $entity, + LockMode|int $lockMode, + DateTimeInterface|int|null $lockVersion = null + ): void { throw new RuntimeException(__METHOD__ . ' not yet implemented'); } /** * Gets the EventManager used by the EntityManager. - * - * @return \Doctrine\Common\EventManager */ - public function getEventManager() + public function getEventManager(): \Doctrine\Common\EventManager { throw new RuntimeException(__METHOD__ . ' not yet implemented'); } /** * Gets the Configuration used by the EntityManager. - * - * @return Configuration */ - public function getConfiguration() + public function getConfiguration(): Configuration { throw new RuntimeException(__METHOD__ . ' not yet implemented'); } /** * Check if the Entity manager is open or closed. - * - * @return bool */ - public function isOpen() + public function isOpen(): bool { // No database connection, always open. return true; @@ -572,27 +440,8 @@ public function isOpen() /** * Gets the UnitOfWork used by the EntityManager to coordinate operations. - * - * @return UnitOfWork */ - public function getUnitOfWork() - { - throw new RuntimeException(__METHOD__ . ' not yet implemented'); - } - - /** - * Gets a hydrator for the given hydration mode. - * - * This method caches the hydrator instances which is used for all queries that don't - * selectively iterate over the result. - * - * @deprecated - * - * @param string|int $hydrationMode - * - * @return \Doctrine\ORM\Internal\Hydration\AbstractHydrator - */ - public function getHydrator($hydrationMode) + public function getUnitOfWork(): \Doctrine\ORM\UnitOfWork { throw new RuntimeException(__METHOD__ . ' not yet implemented'); } @@ -602,77 +451,55 @@ public function getHydrator($hydrationMode) * * @param string|int $hydrationMode * - * @return \Doctrine\ORM\Internal\Hydration\AbstractHydrator - * * @throws ORMException */ - public function newHydrator($hydrationMode) + public function newHydrator($hydrationMode): \Doctrine\ORM\Internal\Hydration\AbstractHydrator { throw new RuntimeException(__METHOD__ . ' not yet implemented'); } /** * Gets the proxy factory used by the EntityManager to create entity proxies. - * - * @return \Doctrine\ORM\Proxy\ProxyFactory */ - public function getProxyFactory() + public function getProxyFactory(): \Doctrine\ORM\Proxy\ProxyFactory { throw new RuntimeException(__METHOD__ . ' not yet implemented'); } /** * Gets the enabled filters. - * - * @return \Doctrine\ORM\Query\FilterCollection The active filter collection. */ - public function getFilters() + public function getFilters(): \Doctrine\ORM\Query\FilterCollection { throw new RuntimeException(__METHOD__ . ' not yet implemented'); } /** * Checks whether the state of the filter collection is clean. - * - * @return boolean True, if the filter collection is clean. */ - public function isFiltersStateClean() + public function isFiltersStateClean(): bool { throw new RuntimeException(__METHOD__ . ' not yet implemented'); } /** * Checks whether the Entity Manager has filters. - * - * @return boolean True, if the EM has a filter collection. */ - public function hasFilters() + public function hasFilters(): bool { throw new RuntimeException(__METHOD__ . ' not yet implemented'); } + public static function setDefaultMappingDriver(MappingDriver $driver): void + { + self::$defaultMappingDriver = $driver; + } + private static function getDefaultMappingDriver(): MappingDriver { if (self::$defaultMappingDriver === null) { - // Hack: reproduce the logic of AnnotationRegistry::registerFile, - // which is a weird autoloader of sorts. By using class_exists - // instead of AnnotationRegistry::registerFile(), we're able to hit - // the file through normal Composer autoloading and avoid having to - // worry about the relative path to the vendor/ directory. - class_exists(DoctrineAnnotations::class); - if (class_exists(SimpleAnnotationReader::class)) { - /** - * In Annotations:2.x, SimpleAnnotationReader was removed. This - * re-adds the type info that won't be available in high - * dependencies. - * @var \Doctrine\Common\Annotations\Reader&SimpleAnnotationReader - */ - $reader = new SimpleAnnotationReader(); - $reader->addNamespace('Doctrine\ORM\Mapping'); - } else { - $reader = new AnnotationReader(); - } - self::$defaultMappingDriver = new AnnotationDriver($reader); + $driver = new AttributeDriver(['.']); + self::$defaultMappingDriver = $driver; } return self::$defaultMappingDriver; } diff --git a/src/InMemoryRepository.php b/src/InMemoryRepository.php index 5d33b38..aeb1772 100644 --- a/src/InMemoryRepository.php +++ b/src/InMemoryRepository.php @@ -5,23 +5,26 @@ namespace Firehed\Mocktrine; use Doctrine\Common\Collections\{ + AbstractLazyCollection, ArrayCollection, - Collection, Criteria, Expr, Selectable, }; +use Doctrine\DBAL\LockMode; use Doctrine\Persistence\Mapping\{ ClassMetadata as ClassMetadataInterface, RuntimeReflectionService, }; use Doctrine\Persistence\Mapping\Driver\MappingDriver; use Doctrine\Persistence\ObjectRepository; +use Doctrine\ORM\EntityRepository; use Doctrine\ORM\ORMException; use Doctrine\ORM\Mapping\{ ClassMetadata, MappingException, }; +use Doctrine\ORM\Persisters\Exception\InvalidOrientation; use DomainException; use ReflectionClass; use TypeError; @@ -42,8 +45,10 @@ * * @implements ObjectRepository * @implements Selectable + * + * @extends EntityRepository */ -class InMemoryRepository implements ObjectRepository, Selectable +class InMemoryRepository extends EntityRepository implements ObjectRepository, Selectable { /** * @var class-string @@ -130,11 +135,9 @@ public function remove(object $entity): void /** * Finds an object by its primary key / identifier. * - * @param mixed $id The identifier. - * * @return ?Entity The object. */ - public function find($id) + public function find(mixed $id, LockMode|int|null $lockMode = null, ?int $lockVersion = null): ?object { return $this->findOneBy([$this->idField => $id]); } @@ -144,7 +147,7 @@ public function find($id) * * @return Entity[] The objects. */ - public function findAll() + public function findAll(): array { return $this->findBy([]); } @@ -158,14 +161,12 @@ public function findAll() * * @param array $criteria * @param array|null $orderBy - * @param int|null $limit - * @param int|null $offset * * @return Entity[] The objects. * * @throws UnexpectedValueException */ - public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null) + public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array { $expr = Criteria::expr(); $crit = Criteria::create(); @@ -184,7 +185,7 @@ public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $ foreach ($orderBy as $field => $direction) { $direction = strtoupper(trim($direction)); if ($direction !== Criteria::ASC && $direction !== Criteria::DESC) { - throw ORMException::invalidOrientation($this->getClassName(), $field); + throw InvalidOrientation::fromClassNameAndField($this->getClassName(), $field); } } $crit->orderBy($orderBy); @@ -207,7 +208,7 @@ public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $ * * @param array $criteria */ - public function count(array $criteria): int + public function count(array $criteria = []): int { return count($this->findBy($criteria)); } @@ -219,7 +220,7 @@ public function count(array $criteria): int * * @return ?Entity The object. */ - public function findOneBy(array $criteria) + public function findOneBy(array $criteria, ?array $orderBy = null): ?object { $results = $this->findBy($criteria); if (count($results) > 0) { @@ -241,12 +242,10 @@ public function getClassName(): string /** * Selectable implementation * {@inheritdoc} - * - * @return Collection */ - public function matching(Criteria $criteria): Collection + public function matching(Criteria $criteria): AbstractLazyCollection&Selectable { - return new ArrayCollection($this->doMatch($criteria)); + return new ArrayALC(new ArrayCollection($this->doMatch($criteria))); } /** diff --git a/tests/CriteriaEvaluatorTest.php b/tests/CriteriaEvaluatorTest.php index 4c75217..e5f4fbe 100644 --- a/tests/CriteriaEvaluatorTest.php +++ b/tests/CriteriaEvaluatorTest.php @@ -5,9 +5,8 @@ namespace Firehed\Mocktrine; use DateTimeImmutable; -use Doctrine\Common\Annotations\AnnotationReader; use Doctrine\Common\Collections\Criteria; -use Doctrine\ORM\Mapping\Driver\AnnotationDriver; +use Doctrine\ORM\Mapping\Driver\AttributeDriver; use Doctrine\Persistence\Mapping\ClassMetadata; use Firehed\Mocktrine\Entities\GrabBag; use PHPUnit\Framework\Attributes\CoversClass; @@ -27,8 +26,7 @@ class CriteriaEvaluatorTest extends \PHPUnit\Framework\TestCase public function setUp(): void { - $reader = new AnnotationReader(); - $em = new InMemoryEntityManager(new AnnotationDriver($reader)); + $em = new InMemoryEntityManager(new AttributeDriver(['.'])); $repo = $em->getRepository(GrabBag::class); $this->entities = [ new GrabBag(true, 30, 'hello', new DateTimeImmutable()), diff --git a/tests/Entities/XmlMappings/Firehed.Mocktrine.Entities.GrabBag.dcm.xml b/tests/Entities/XmlMappings/Firehed.Mocktrine.Entities.GrabBag.dcm.xml index 9a71cf3..abe9bbf 100644 --- a/tests/Entities/XmlMappings/Firehed.Mocktrine.Entities.GrabBag.dcm.xml +++ b/tests/Entities/XmlMappings/Firehed.Mocktrine.Entities.GrabBag.dcm.xml @@ -1,7 +1,7 @@ - diff --git a/tests/Entities/XmlMappings/Firehed.Mocktrine.Entities.Group.dcm.xml b/tests/Entities/XmlMappings/Firehed.Mocktrine.Entities.Group.dcm.xml index e6bed5e..bf209ad 100644 --- a/tests/Entities/XmlMappings/Firehed.Mocktrine.Entities.Group.dcm.xml +++ b/tests/Entities/XmlMappings/Firehed.Mocktrine.Entities.Group.dcm.xml @@ -1,7 +1,7 @@ - diff --git a/tests/Entities/XmlMappings/Firehed.Mocktrine.Entities.Node.dcm.xml b/tests/Entities/XmlMappings/Firehed.Mocktrine.Entities.Node.dcm.xml index 157da85..8972901 100644 --- a/tests/Entities/XmlMappings/Firehed.Mocktrine.Entities.Node.dcm.xml +++ b/tests/Entities/XmlMappings/Firehed.Mocktrine.Entities.Node.dcm.xml @@ -1,7 +1,7 @@ - diff --git a/tests/Entities/XmlMappings/Firehed.Mocktrine.Entities.ReadonlyConstructorId.dcm.xml b/tests/Entities/XmlMappings/Firehed.Mocktrine.Entities.ReadonlyConstructorId.dcm.xml index fab31fc..de95cac 100644 --- a/tests/Entities/XmlMappings/Firehed.Mocktrine.Entities.ReadonlyConstructorId.dcm.xml +++ b/tests/Entities/XmlMappings/Firehed.Mocktrine.Entities.ReadonlyConstructorId.dcm.xml @@ -1,7 +1,7 @@ - diff --git a/tests/Entities/XmlMappings/Firehed.Mocktrine.Entities.ReadonlyGeneratedId.dcm.xml b/tests/Entities/XmlMappings/Firehed.Mocktrine.Entities.ReadonlyGeneratedId.dcm.xml index 95b2398..b79af19 100644 --- a/tests/Entities/XmlMappings/Firehed.Mocktrine.Entities.ReadonlyGeneratedId.dcm.xml +++ b/tests/Entities/XmlMappings/Firehed.Mocktrine.Entities.ReadonlyGeneratedId.dcm.xml @@ -1,7 +1,7 @@ - diff --git a/tests/Entities/XmlMappings/Firehed.Mocktrine.Entities.StringId.dcm.xml b/tests/Entities/XmlMappings/Firehed.Mocktrine.Entities.StringId.dcm.xml index 310ffe1..de06d17 100644 --- a/tests/Entities/XmlMappings/Firehed.Mocktrine.Entities.StringId.dcm.xml +++ b/tests/Entities/XmlMappings/Firehed.Mocktrine.Entities.StringId.dcm.xml @@ -1,7 +1,7 @@ - diff --git a/tests/Entities/XmlMappings/Firehed.Mocktrine.Entities.TypedId.dcm.xml b/tests/Entities/XmlMappings/Firehed.Mocktrine.Entities.TypedId.dcm.xml index e678874..3207619 100644 --- a/tests/Entities/XmlMappings/Firehed.Mocktrine.Entities.TypedId.dcm.xml +++ b/tests/Entities/XmlMappings/Firehed.Mocktrine.Entities.TypedId.dcm.xml @@ -1,7 +1,7 @@ - diff --git a/tests/Entities/XmlMappings/Firehed.Mocktrine.Entities.UnspecifiedId.dcm.xml b/tests/Entities/XmlMappings/Firehed.Mocktrine.Entities.UnspecifiedId.dcm.xml index b4a2294..83146e6 100644 --- a/tests/Entities/XmlMappings/Firehed.Mocktrine.Entities.UnspecifiedId.dcm.xml +++ b/tests/Entities/XmlMappings/Firehed.Mocktrine.Entities.UnspecifiedId.dcm.xml @@ -1,7 +1,7 @@ - diff --git a/tests/Entities/XmlMappings/Firehed.Mocktrine.Entities.User.dcm.xml b/tests/Entities/XmlMappings/Firehed.Mocktrine.Entities.User.dcm.xml index dcc8759..6a3bbfd 100644 --- a/tests/Entities/XmlMappings/Firehed.Mocktrine.Entities.User.dcm.xml +++ b/tests/Entities/XmlMappings/Firehed.Mocktrine.Entities.User.dcm.xml @@ -1,7 +1,7 @@ - diff --git a/tests/InMemoryEntityManagerTest.php b/tests/InMemoryEntityManagerTest.php index c5fa899..244359d 100644 --- a/tests/InMemoryEntityManagerTest.php +++ b/tests/InMemoryEntityManagerTest.php @@ -4,9 +4,8 @@ namespace Firehed\Mocktrine; -use Doctrine\Common\Annotations\AnnotationReader; use Doctrine\ORM\EntityManagerInterface; -use Doctrine\ORM\Mapping\Driver\AnnotationDriver; +use Doctrine\ORM\Mapping\Driver\AttributeDriver; use Doctrine\Persistence\ObjectRepository; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\Small; @@ -19,8 +18,7 @@ class InMemoryEntityManagerTest extends \PHPUnit\Framework\TestCase { protected function getEntityManager(): InMemoryEntityManager { - $reader = new AnnotationReader(); - return new InMemoryEntityManager(new AnnotationDriver($reader)); + return new InMemoryEntityManager(new AttributeDriver(['.'])); } public function testFindWithNoEntity(): void @@ -33,7 +31,7 @@ public function testFindWithPersistedEntity(): void { $user = new Entities\User('1@example.com', 'last', 10); $em = $this->getEntityManager(); - $em->merge($user); // This starts managing the entity + $em->persist($user); // This starts managing the entity $this->assertSame($user, $em->find(Entities\User::class, 10)); } @@ -97,7 +95,7 @@ public function testRemoveMakesQueryingEntityInaccessable(): void { $node = new Entities\Node(); $em = $this->getEntityManager(); - $em->merge($node); + $em->persist($node); $this->assertSame( $node, $em->find(Entities\Node::class, $node->getNodeId()), diff --git a/tests/InMemoryRepositoryTest.php b/tests/InMemoryRepositoryTest.php index 2283609..b3efa41 100644 --- a/tests/InMemoryRepositoryTest.php +++ b/tests/InMemoryRepositoryTest.php @@ -4,11 +4,10 @@ namespace Firehed\Mocktrine; -use Doctrine\Common\Annotations\AnnotationReader; use Doctrine\Common\Collections\Criteria; use Doctrine\Persistence\ObjectRepository; -use Doctrine\ORM\ORMException; -use Doctrine\ORM\Mapping\Driver\AnnotationDriver; +use Doctrine\ORM\Exception\ORMException; +use Doctrine\ORM\Mapping\Driver\AttributeDriver; use Doctrine\ORM\Mapping\MappingException; use Doctrine\Persistence\Mapping\Driver\MappingDriver; use Error; @@ -27,8 +26,7 @@ class InMemoryRepositoryTest extends \PHPUnit\Framework\TestCase public function setUp(): void { - $reader = new AnnotationReader(); - $this->driver = new AnnotationDriver($reader); + $this->driver = new AttributeDriver(['.']); } public function testConstruct(): void