Failed Conditions
Pull Request — 2.6 (#7506)
by
unknown
09:52
created

ensureTestGeneratedDeprecationMessages()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
namespace Doctrine\Tests\ORM\Functional;
4
5
use Doctrine\DBAL\DriverManager;
6
use Doctrine\DBAL\Logging\DebugStack;
7
use Doctrine\DBAL\Logging\SQLLogger;
8
use Doctrine\ORM\Configuration;
9
use Doctrine\ORM\EntityManager;
10
use Doctrine\ORM\Proxy\Proxy;
11
use Doctrine\ORM\Tools\SchemaTool;
12
use Doctrine\Tests\Models\Generic\DateTimeModel;
13
use Doctrine\Tests\OrmFunctionalTestCase;
14
use Doctrine\Tests\VerifyDeprecations;
15
16
class MergeProxiesTest extends OrmFunctionalTestCase
17
{
18
    use VerifyDeprecations;
19
20
    /**
21
     * {@inheritDoc}
22
     */
23
    protected function setUp()
24
    {
25
        $this->useModelSet('generic');
26
27
        parent::setUp();
28
    }
29
30
    /** @after */
31
    public function ensureTestGeneratedDeprecationMessages() : void
32
    {
33
        $this->assertHasDeprecationMessages();
34
    }
35
36
    /**
37
     * @group DDC-1392
38
     * @group DDC-1734
39
     * @group DDC-3368
40
     * @group #1172
41
     */
42
    public function testMergeDetachedUnInitializedProxy()
43
    {
44
        $detachedUninitialized = $this->_em->getReference(DateTimeModel::class, 123);
45
46
        $this->_em->clear();
47
48
        $managed = $this->_em->getReference(DateTimeModel::class, 123);
49
50
        $this->assertSame($managed, $this->_em->merge($detachedUninitialized));
0 ignored issues
show
Deprecated Code introduced by
The function Doctrine\ORM\EntityManager::merge() has been deprecated: 2.7 This method is being removed from the ORM and won't have any replacement ( Ignorable by Annotation )

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

50
        $this->assertSame($managed, /** @scrutinizer ignore-deprecated */ $this->_em->merge($detachedUninitialized));

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
51
52
        $this->assertFalse($managed->__isInitialized());
53
        $this->assertFalse($detachedUninitialized->__isInitialized());
54
    }
55
56
    /**
57
     * @group DDC-1392
58
     * @group DDC-1734
59
     * @group DDC-3368
60
     * @group #1172
61
     */
62
    public function testMergeUnserializedUnInitializedProxy()
63
    {
64
        $detachedUninitialized = $this->_em->getReference(DateTimeModel::class, 123);
65
66
        $this->_em->clear();
67
68
        $managed = $this->_em->getReference(DateTimeModel::class, 123);
69
70
        $this->assertSame(
71
            $managed,
72
            $this->_em->merge(unserialize(serialize($this->_em->merge($detachedUninitialized))))
0 ignored issues
show
Deprecated Code introduced by
The function Doctrine\ORM\EntityManager::merge() has been deprecated: 2.7 This method is being removed from the ORM and won't have any replacement ( Ignorable by Annotation )

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

72
            $this->_em->merge(unserialize(serialize(/** @scrutinizer ignore-deprecated */ $this->_em->merge($detachedUninitialized))))

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
73
        );
74
75
        $this->assertFalse($managed->__isInitialized());
76
        $this->assertFalse($detachedUninitialized->__isInitialized());
77
    }
78
79
    /**
80
     * @group DDC-1392
81
     * @group DDC-1734
82
     * @group DDC-3368
83
     * @group #1172
84
     */
85
    public function testMergeManagedProxy()
86
    {
87
        $managed = $this->_em->getReference(DateTimeModel::class, 123);
88
89
        $this->assertSame($managed, $this->_em->merge($managed));
0 ignored issues
show
Deprecated Code introduced by
The function Doctrine\ORM\EntityManager::merge() has been deprecated: 2.7 This method is being removed from the ORM and won't have any replacement ( Ignorable by Annotation )

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

89
        $this->assertSame($managed, /** @scrutinizer ignore-deprecated */ $this->_em->merge($managed));

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
90
91
        $this->assertFalse($managed->__isInitialized());
92
    }
93
94
    /**
95
     * @group DDC-1392
96
     * @group DDC-1734
97
     * @group DDC-3368
98
     * @group #1172
99
     *
100
     * Bug discovered while working on DDC-2704 - merging towards un-initialized proxies does not initialize them,
101
     * causing merged data to be lost when they are actually initialized
102
     */
103
    public function testMergeWithExistingUninitializedManagedProxy()
104
    {
105
        $date = new DateTimeModel();
106
107
        $this->_em->persist($date);
108
        $this->_em->flush($date);
109
        $this->_em->clear();
110
111
        $managed = $this->_em->getReference(DateTimeModel::class, $date->id);
112
113
        $this->assertInstanceOf(Proxy::class, $managed);
114
        $this->assertFalse($managed->__isInitialized());
115
116
        $date->date = $dateTime = new \DateTime();
117
118
        $this->assertSame($managed, $this->_em->merge($date));
0 ignored issues
show
Deprecated Code introduced by
The function Doctrine\ORM\EntityManager::merge() has been deprecated: 2.7 This method is being removed from the ORM and won't have any replacement ( Ignorable by Annotation )

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

118
        $this->assertSame($managed, /** @scrutinizer ignore-deprecated */ $this->_em->merge($date));

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
119
        $this->assertTrue($managed->__isInitialized());
120
        $this->assertSame($dateTime, $managed->date, 'Data was merged into the proxy after initialization');
121
    }
122
123
    /**
124
     * @group DDC-1392
125
     * @group DDC-1734
126
     * @group DDC-3368
127
     * @group #1172
128
     */
129
    public function testMergingProxyFromDifferentEntityManagerWithExistingManagedInstanceDoesNotReplaceInitializer()
130
    {
131
        $em1 = $this->createEntityManager($logger1 = new DebugStack());
132
        $em2 = $this->createEntityManager($logger2 = new DebugStack());
133
134
        $file1 = new DateTimeModel();
135
        $file2 = new DateTimeModel();
136
137
        $em1->persist($file1);
138
        $em2->persist($file2);
139
        $em1->flush();
140
        $em2->flush();
141
        $em1->clear();
142
        $em2->clear();
143
144
        $queryCount1 = count($logger1->queries);
145
        $queryCount2 = count($logger2->queries);
146
147
        $proxy1  = $em1->getReference(DateTimeModel::class, $file1->id);
148
        $proxy2  = $em2->getReference(DateTimeModel::class, $file1->id);
149
        $merged2 = $em2->merge($proxy1);
0 ignored issues
show
Deprecated Code introduced by
The function Doctrine\ORM\EntityManager::merge() has been deprecated: 2.7 This method is being removed from the ORM and won't have any replacement ( Ignorable by Annotation )

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

149
        $merged2 = /** @scrutinizer ignore-deprecated */ $em2->merge($proxy1);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
150
151
        $this->assertNotSame($proxy1, $merged2);
152
        $this->assertSame($proxy2, $merged2);
153
154
        $this->assertFalse($proxy1->__isInitialized());
155
        $this->assertFalse($proxy2->__isInitialized());
156
157
        $proxy1->__load();
158
159
        $this->assertCount(
160
            $queryCount1 + 1,
161
            $logger1->queries,
162
            'Loading the first proxy was done through the first entity manager'
163
        );
164
        $this->assertCount(
165
            $queryCount2,
166
            $logger2->queries,
167
            'No queries were executed on the second entity manager, as it is unrelated with the first proxy'
168
        );
169
170
        $proxy2->__load();
171
172
        $this->assertCount(
173
            $queryCount1 + 1,
174
            $logger1->queries,
175
            'Loading the second proxy does not affect the first entity manager'
176
        );
177
        $this->assertCount(
178
            $queryCount2 + 1,
179
            $logger2->queries,
180
            'Loading of the second proxy instance was done through the second entity manager'
181
        );
182
    }
183
184
    /**
185
     * @group DDC-1392
186
     * @group DDC-1734
187
     * @group DDC-3368
188
     * @group #1172
189
     */
190
    public function testMergingUnInitializedProxyDoesNotInitializeIt()
191
    {
192
        $em1 = $this->createEntityManager($logger1 = new DebugStack());
193
        $em2 = $this->createEntityManager($logger2 = new DebugStack());
194
195
        $file1 = new DateTimeModel();
196
        $file2 = new DateTimeModel();
197
198
        $em1->persist($file1);
199
        $em2->persist($file2);
200
        $em1->flush();
201
        $em2->flush();
202
        $em1->clear();
203
        $em2->clear();
204
205
        $queryCount1 = count($logger1->queries);
206
        $queryCount2 = count($logger1->queries);
207
208
        $unManagedProxy = $em1->getReference(DateTimeModel::class, $file1->id);
209
        $mergedInstance = $em2->merge($unManagedProxy);
0 ignored issues
show
Deprecated Code introduced by
The function Doctrine\ORM\EntityManager::merge() has been deprecated: 2.7 This method is being removed from the ORM and won't have any replacement ( Ignorable by Annotation )

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

209
        $mergedInstance = /** @scrutinizer ignore-deprecated */ $em2->merge($unManagedProxy);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
210
211
        $this->assertNotInstanceOf(Proxy::class, $mergedInstance);
212
        $this->assertNotSame($unManagedProxy, $mergedInstance);
213
        $this->assertFalse($unManagedProxy->__isInitialized());
214
215
        $this->assertCount(
216
            $queryCount1,
217
            $logger1->queries,
218
            'Loading the merged instance affected only the first entity manager'
219
        );
220
        $this->assertCount(
221
            $queryCount1 + 1,
222
            $logger2->queries,
223
            'Loading the merged instance was done via the second entity manager'
224
        );
225
226
        $unManagedProxy->__load();
227
228
        $this->assertCount(
229
            $queryCount1 + 1,
230
            $logger1->queries,
231
            'Loading the first proxy was done through the first entity manager'
232
        );
233
        $this->assertCount(
234
            $queryCount2 + 1,
235
            $logger2->queries,
236
            'No queries were executed on the second entity manager, as it is unrelated with the first proxy'
237
        );
238
    }
239
240
    /**
241
     * @param SQLLogger $logger
242
     *
243
     * @return EntityManager
244
     */
245
    private function createEntityManager(SQLLogger $logger)
246
    {
247
        $config = new Configuration();
248
249
        $config->setProxyDir(realpath(__DIR__ . '/../../Proxies'));
250
        $config->setProxyNamespace('Doctrine\Tests\Proxies');
251
        $config->setMetadataDriverImpl($config->newDefaultAnnotationDriver(
252
            [realpath(__DIR__ . '/../../Models/Cache')],
253
            true
254
        ));
255
        $config->setSQLLogger($logger);
256
257
        // always runs on sqlite to prevent multi-connection race-conditions with the test suite
258
        // multi-connection is not relevant for the purpose of checking locking here, but merely
259
        // to stub out DB-level access and intercept it
260
        $connection = DriverManager::getConnection(
261
            [
262
                'driver' => 'pdo_sqlite',
263
                'memory' => true
264
            ],
265
            $config
266
        );
267
268
269
        $entityManager = EntityManager::create($connection, $config);
270
271
        (new SchemaTool($entityManager))->createSchema([$entityManager->getClassMetadata(DateTimeModel::class)]);
272
273
        return $entityManager;
274
    }
275
}
276