Completed
Pull Request — master (#7448)
by Ilya
11:47
created

EntityManagerTest::testIsOpen()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 0
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Tests\ORM;
6
7
use Doctrine\Common\EventManager;
8
use Doctrine\DBAL\Connection;
9
use Doctrine\ORM\Configuration;
10
use Doctrine\ORM\EntityManager;
11
use Doctrine\ORM\Event\PreFlushEventArgs;
12
use Doctrine\ORM\Events;
13
use Doctrine\ORM\Exception\EntityManagerClosed;
14
use Doctrine\ORM\Mapping\ClassMetadataFactory;
15
use Doctrine\ORM\Mapping\Driver\MappingDriver;
16
use Doctrine\ORM\ORMInvalidArgumentException;
17
use Doctrine\ORM\Proxy\Factory\ProxyFactory;
18
use Doctrine\ORM\Query;
19
use Doctrine\ORM\Query\ResultSetMapping;
20
use Doctrine\ORM\QueryBuilder;
21
use Doctrine\ORM\UnitOfWork;
22
use Doctrine\Tests\Models\CMS\CmsUser;
23
use Doctrine\Tests\Models\GeoNames\Country;
24
use Doctrine\Tests\Models\IdentityIsAssociation\SimpleId;
25
use Doctrine\Tests\Models\IdentityIsAssociation\ToOneAssociationIdToSimpleId;
26
use Doctrine\Tests\Models\IdentityIsAssociation\ToOneCompositeAssociationToMultipleSimpleId;
27
use Doctrine\Tests\OrmTestCase;
28
29
class EntityManagerTest extends OrmTestCase
30
{
31
    /** @var EntityManager */
32
    private $em;
33
34
    public function setUp() : void
35
    {
36
        parent::setUp();
37
38
        $this->em = $this->getTestEntityManager();
39
    }
40
41
    /**
42
     * @group DDC-899
43
     */
44
    public function testIsOpen() : void
45
    {
46
        self::assertTrue($this->em->isOpen());
47
        $this->em->close();
48
        self::assertFalse($this->em->isOpen());
49
    }
50
51
    public function testGetConnection() : void
52
    {
53
        self::assertInstanceOf(Connection::class, $this->em->getConnection());
54
    }
55
56
    public function testGetMetadataFactory() : void
57
    {
58
        self::assertInstanceOf(ClassMetadataFactory::class, $this->em->getMetadataFactory());
59
    }
60
61
    public function testGetConfiguration() : void
62
    {
63
        self::assertInstanceOf(Configuration::class, $this->em->getConfiguration());
64
    }
65
66
    public function testGetUnitOfWork() : void
67
    {
68
        self::assertInstanceOf(UnitOfWork::class, $this->em->getUnitOfWork());
69
    }
70
71
    public function testGetProxyFactory() : void
72
    {
73
        self::assertInstanceOf(ProxyFactory::class, $this->em->getProxyFactory());
74
    }
75
76
    public function testGetEventManager() : void
77
    {
78
        self::assertInstanceOf(EventManager::class, $this->em->getEventManager());
79
    }
80
81
    public function testCreateNativeQuery() : void
82
    {
83
        $rsm   = new ResultSetMapping();
84
        $query = $this->em->createNativeQuery('SELECT foo', $rsm);
85
86
        self::assertSame('SELECT foo', $query->getSql());
87
    }
88
89
    public function testCreateQueryBuilder() : void
90
    {
91
        self::assertInstanceOf(QueryBuilder::class, $this->em->createQueryBuilder());
92
    }
93
94
    public function testCreateQueryBuilderAliasValid() : void
95
    {
96
        $q  = $this->em->createQueryBuilder()
97
             ->select('u')->from(CmsUser::class, 'u');
98
        $q2 = clone $q;
99
100
        self::assertEquals('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u', $q->getQuery()->getDql());
101
        self::assertEquals('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u', $q2->getQuery()->getDql());
102
103
        $q3 = clone $q;
104
105
        self::assertEquals('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u', $q3->getQuery()->getDql());
106
    }
107
108
    public function testCreateQueryDqlIsOptional() : void
109
    {
110
        self::assertInstanceOf(Query::class, $this->em->createQuery());
111
    }
112
113
    public function testGetPartialReference() : void
114
    {
115
        $user = $this->em->getPartialReference(CmsUser::class, 42);
116
        self::assertTrue($this->em->contains($user));
117
        self::assertEquals(42, $user->id);
118
        self::assertNull($user->getName());
119
    }
120
121
    public function testCreateQuery() : void
122
    {
123
        $q = $this->em->createQuery('SELECT 1');
124
        self::assertInstanceOf(Query::class, $q);
125
        self::assertEquals('SELECT 1', $q->getDql());
126
    }
127
128
    public static function dataMethodsAffectedByNoObjectArguments()
129
    {
130
        return [
131
            ['persist'],
132
            ['remove'],
133
            ['refresh'],
134
        ];
135
    }
136
137
    /**
138
     * @dataProvider dataMethodsAffectedByNoObjectArguments
139
     */
140
    public function testThrowsExceptionOnNonObjectValues($methodName) : void
141
    {
142
        $this->expectException(ORMInvalidArgumentException::class);
143
        $this->expectExceptionMessage('EntityManager#' . $methodName . '() expects parameter 1 to be an entity object, NULL given.');
144
145
        $this->em->{$methodName}(null);
146
    }
147
148
    public static function dataAffectedByErrorIfClosedException()
149
    {
150
        return [
151
            ['flush'],
152
            ['persist'],
153
            ['remove'],
154
            ['refresh'],
155
        ];
156
    }
157
158
    /**
159
     * @dataProvider dataAffectedByErrorIfClosedException
160
     * @param string $methodName
161
     */
162
    public function testAffectedByErrorIfClosedException($methodName) : void
163
    {
164
        $this->expectException(EntityManagerClosed::class);
165
        $this->expectExceptionMessage('closed');
166
167
        $this->em->close();
168
        $this->em->{$methodName}(new \stdClass());
169
    }
170
171
    public function dataToBeReturnedByTransactional()
172
    {
173
        return [
174
            [null],
175
            [false],
176
            ['foo'],
177
        ];
178
    }
179
180
    /**
181
     * @dataProvider dataToBeReturnedByTransactional
182
     */
183
    public function testTransactionalAcceptsReturn($value) : void
184
    {
185
        self::assertSame(
186
            $value,
187
            $this->em->transactional(function ($em) use ($value) {
188
                return $value;
189
            })
190
        );
191
    }
192
193
    public function testTransactionalAcceptsVariousCallables() : void
194
    {
195
        self::assertSame('callback', $this->em->transactional([$this, 'transactionalCallback']));
196
    }
197
198
    public function transactionalCallback($em)
199
    {
200
        self::assertSame($this->em, $em);
201
        return 'callback';
202
    }
203
204
    public function testCreateInvalidConnection() : void
205
    {
206
        $this->expectException(\InvalidArgumentException::class);
207
        $this->expectExceptionMessage('Invalid $connection argument of type integer given: "1".');
208
209
        $config = new Configuration();
210
        $config->setMetadataDriverImpl($this->createMock(MappingDriver::class));
211
        EntityManager::create(1, $config);
0 ignored issues
show
Bug introduced by
1 of type integer is incompatible with the type Doctrine\DBAL\Connection|array<mixed,mixed> expected by parameter $connection of Doctrine\ORM\EntityManager::create(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

211
        EntityManager::create(/** @scrutinizer ignore-type */ 1, $config);
Loading history...
212
    }
213
214
    /**
215
     * @group #5796
216
     */
217
    public function testTransactionalReThrowsThrowables() : void
218
    {
219
        try {
220
            $this->em->transactional(function () {
221
                (function (array $value) {
222
                    // this only serves as an IIFE that throws a `TypeError`
223
                })(null);
224
            });
225
226
            self::fail('TypeError expected to be thrown');
227
        } catch (\TypeError $ignored) {
228
            self::assertFalse($this->em->isOpen());
229
        }
230
    }
231
232
    /**
233
     * @group 6017
234
     */
235
    public function testClearManager() : void
236
    {
237
        $entity = new Country(456, 'United Kingdom');
238
239
        $this->em->persist($entity);
240
241
        self::assertTrue($this->em->contains($entity));
242
243
        $this->em->clear();
244
245
        self::assertFalse($this->em->contains($entity));
246
    }
247
248
    public function testGetReferenceRetrievesReferencesWithGivenProxiesAsIdentifiers() : void
249
    {
250
        $simpleIdReference = $this->em->getReference(
251
            SimpleId::class,
252
            ['id' => 123]
253
        );
254
        /** @var GhostObjectInterface|ToOneAssociationIdToSimpleId $nestedReference */
255
        $nestedIdReference = $this->em->getReference(
256
            ToOneAssociationIdToSimpleId::class,
257
            ['simpleId' => $simpleIdReference]
258
        );
259
260
        self::assertInstanceOf(ToOneAssociationIdToSimpleId::class, $nestedIdReference);
261
        self::assertSame($simpleIdReference, $nestedIdReference->simpleId);
262
        self::assertTrue($this->em->contains($simpleIdReference));
263
        self::assertTrue($this->em->contains($nestedIdReference));
264
    }
265
266
    public function testGetReferenceRetrievesReferencesWithGivenProxiesAsIdentifiersEvenIfIdentifierOrderIsSwapped() : void
267
    {
268
        $simpleIdReferenceA = $this->em->getReference(
269
            SimpleId::class,
270
            ['id' => 123]
271
        );
272
        $simpleIdReferenceB = $this->em->getReference(
273
            SimpleId::class,
274
            ['id' => 456]
275
        );
276
        /** @var GhostObjectInterface|ToOneCompositeAssociationToMultipleSimpleId $nestedIdReference */
277
        $nestedIdReference = $this->em->getReference(
278
            ToOneCompositeAssociationToMultipleSimpleId::class,
279
            ['simpleIdB' => $simpleIdReferenceB, 'simpleIdA' => $simpleIdReferenceA]
280
        );
281
282
        self::assertInstanceOf(ToOneCompositeAssociationToMultipleSimpleId::class, $nestedIdReference);
283
        self::assertSame($simpleIdReferenceA, $nestedIdReference->simpleIdA);
284
        self::assertSame($simpleIdReferenceB, $nestedIdReference->simpleIdB);
285
        self::assertTrue($this->em->contains($simpleIdReferenceA));
286
        self::assertTrue($this->em->contains($simpleIdReferenceB));
287
        self::assertTrue($this->em->contains($nestedIdReference));
288
    }
289
290
    public function testCallingFlushInsideFlush()
291
    {
292
        // This flag is used to prevent infinity loop in case of regression
293
        $alreadyInPreFlush = false;
294
295
        $listener = function (PreFlushEventArgs $eventArgs) use (&$alreadyInPreFlush) {
296
            if ($alreadyInPreFlush) {
297
                $this->fail('Flush inside flush called. It should not happened. Fail test to prevent infinity loop');
298
            }
299
            $eventArgs->getEntityManager()->flush();
300
            $alreadyInPreFlush = true;
301
        };
302
303
        $this->expectException(\LogicException::class);
304
        $this->em->getEventManager()->addEventListener(Events::preFlush, $listener);
0 ignored issues
show
Bug introduced by
$listener of type callable is incompatible with the type object expected by parameter $listener of Doctrine\Common\EventManager::addEventListener(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

304
        $this->em->getEventManager()->addEventListener(Events::preFlush, /** @scrutinizer ignore-type */ $listener);
Loading history...
305
        $this->em->flush();
306
    }
307
}
308