Passed
Pull Request — 2.6 (#7861)
by Gabriel
08:02
created

PersistentCollectionTest::testDoNotModifyUOWForDeferredExplicitOwnerOnClear()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 6
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 10
rs 10
1
<?php
2
3
namespace Doctrine\Tests\ORM;
4
5
use Doctrine\Common\Collections\ArrayCollection;
6
use Doctrine\ORM\Mapping\ClassMetadataInfo;
7
use Doctrine\ORM\PersistentCollection;
8
use Doctrine\ORM\UnitOfWork;
9
use Doctrine\Tests\Mocks\ConnectionMock;
10
use Doctrine\Tests\Mocks\DriverMock;
11
use Doctrine\Tests\Mocks\EntityManagerMock;
12
use Doctrine\Tests\Models\ECommerce\ECommerceCart;
13
use Doctrine\Tests\Models\ECommerce\ECommerceProduct;
14
use Doctrine\Tests\OrmTestCase;
15
16
/**
17
 * Tests the lazy-loading capabilities of the PersistentCollection and the initialization of collections.
18
 * @author Giorgio Sironi <[email protected]>
19
 * @author Austin Morris <[email protected]>
20
 */
21
class PersistentCollectionTest extends OrmTestCase
22
{
23
    /**
24
     * @var PersistentCollection
25
     */
26
    protected $collection;
27
28
    /**
29
     * @var EntityManagerMock
30
     */
31
    private $_emMock;
32
33
    protected function setUp()
34
    {
35
        parent::setUp();
36
37
        $this->_emMock = EntityManagerMock::create(new ConnectionMock([], new DriverMock()));
38
39
        $this->setUpPersistentCollection();
40
    }
41
42
    /**
43
     * Set up the PersistentCollection used for collection initialization tests.
44
     */
45
    public function setUpPersistentCollection()
46
    {
47
        $classMetaData = $this->_emMock->getClassMetadata(ECommerceCart::class);
48
        $this->collection = new PersistentCollection($this->_emMock, $classMetaData, new ArrayCollection);
49
        $this->collection->setInitialized(false);
50
        $this->collection->setOwner(new ECommerceCart(), $classMetaData->getAssociationMapping('products'));
51
    }
52
53
    public function testCanBePutInLazyLoadingMode()
54
    {
55
        $class = $this->_emMock->getClassMetadata(ECommerceProduct::class);
56
        $collection = new PersistentCollection($this->_emMock, $class, new ArrayCollection);
57
        $collection->setInitialized(false);
58
        $this->assertFalse($collection->isInitialized());
59
    }
60
61
    /**
62
     * Test that PersistentCollection::current() initializes the collection.
63
     */
64
    public function testCurrentInitializesCollection()
65
    {
66
        $this->collection->current();
67
        $this->assertTrue($this->collection->isInitialized());
68
    }
69
70
    /**
71
     * Test that PersistentCollection::key() initializes the collection.
72
     */
73
    public function testKeyInitializesCollection()
74
    {
75
        $this->collection->key();
76
        $this->assertTrue($this->collection->isInitialized());
77
    }
78
79
    /**
80
     * Test that PersistentCollection::next() initializes the collection.
81
     */
82
    public function testNextInitializesCollection()
83
    {
84
        $this->collection->next();
85
        $this->assertTrue($this->collection->isInitialized());
86
    }
87
88
    /**
89
     * @group DDC-3382
90
     */
91
    public function testNonObjects()
92
    {
93
        $this->assertEmpty($this->collection);
94
95
        $this->collection->add("dummy");
96
97
        $this->assertNotEmpty($this->collection);
98
99
        $product = new ECommerceProduct();
100
101
        $this->collection->set(1, $product);
102
        $this->collection->set(2, "dummy");
103
        $this->collection->set(3, null);
104
105
        $this->assertSame($product, $this->collection->get(1));
106
        $this->assertSame("dummy", $this->collection->get(2));
107
        $this->assertSame(null, $this->collection->get(3));
108
    }
109
110
    /**
111
     * @group 6110
112
     */
113
    public function testRemovingElementsAlsoRemovesKeys()
114
    {
115
        $dummy = new \stdClass();
116
117
        $this->collection->add($dummy);
118
        $this->assertEquals([0], array_keys($this->collection->toArray()));
119
120
        $this->collection->removeElement($dummy);
121
        $this->assertEquals([], array_keys($this->collection->toArray()));
122
    }
123
124
    /**
125
     * @group 6110
126
     */
127
    public function testClearWillAlsoClearKeys()
128
    {
129
        $this->collection->add(new \stdClass());
130
        $this->collection->clear();
131
        $this->assertEquals([], array_keys($this->collection->toArray()));
132
    }
133
134
    /**
135
     * @group 6110
136
     */
137
    public function testClearWillAlsoResetKeyPositions()
138
    {
139
        $dummy = new \stdClass();
140
141
        $this->collection->add($dummy);
142
        $this->collection->removeElement($dummy);
143
        $this->collection->clear();
144
        $this->collection->add($dummy);
145
        $this->assertEquals([0], array_keys($this->collection->toArray()));
146
    }
147
148
    /**
149
     * @group 6613
150
     * @group 6614
151
     * @group 6616
152
     */
153
    public function testWillKeepNewItemsInDirtyCollectionAfterInitialization() : void
154
    {
155
        /* @var $unitOfWork UnitOfWork|\PHPUnit_Framework_MockObject_MockObject */
156
        $unitOfWork = $this->createMock(UnitOfWork::class);
157
158
        $this->_emMock->setUnitOfWork($unitOfWork);
159
160
        $newElement       = new \stdClass();
161
        $persistedElement = new \stdClass();
162
163
        $this->collection->add($newElement);
164
165
        self::assertFalse($this->collection->isInitialized());
166
        self::assertTrue($this->collection->isDirty());
167
168
        $unitOfWork
169
            ->expects(self::once())
170
            ->method('loadCollection')
171
            ->with($this->collection)
172
            ->willReturnCallback(function (PersistentCollection $persistentCollection) use ($persistedElement) : void {
173
                $persistentCollection->unwrap()->add($persistedElement);
174
            });
175
176
        $this->collection->initialize();
177
178
        self::assertSame([$persistedElement, $newElement], $this->collection->toArray());
179
        self::assertTrue($this->collection->isInitialized());
180
        self::assertTrue($this->collection->isDirty());
181
    }
182
183
    /**
184
     * @group 6613
185
     * @group 6614
186
     * @group 6616
187
     */
188
    public function testWillDeDuplicateNewItemsThatWerePreviouslyPersistedInDirtyCollectionAfterInitialization() : void
189
    {
190
        /* @var $unitOfWork UnitOfWork|\PHPUnit_Framework_MockObject_MockObject */
191
        $unitOfWork = $this->createMock(UnitOfWork::class);
192
193
        $this->_emMock->setUnitOfWork($unitOfWork);
194
195
        $newElement                    = new \stdClass();
196
        $newElementThatIsAlsoPersisted = new \stdClass();
197
        $persistedElement              = new \stdClass();
198
199
        $this->collection->add($newElementThatIsAlsoPersisted);
200
        $this->collection->add($newElement);
201
202
        self::assertFalse($this->collection->isInitialized());
203
        self::assertTrue($this->collection->isDirty());
204
205
        $unitOfWork
206
            ->expects(self::once())
207
            ->method('loadCollection')
208
            ->with($this->collection)
209
            ->willReturnCallback(function (PersistentCollection $persistentCollection) use (
210
                $persistedElement,
211
                $newElementThatIsAlsoPersisted
212
            ) : void {
213
                $persistentCollection->unwrap()->add($newElementThatIsAlsoPersisted);
214
                $persistentCollection->unwrap()->add($persistedElement);
215
            });
216
217
        $this->collection->initialize();
218
219
        self::assertSame(
220
            [$newElementThatIsAlsoPersisted, $persistedElement, $newElement],
221
            $this->collection->toArray()
222
        );
223
        self::assertTrue($this->collection->isInitialized());
224
        self::assertTrue($this->collection->isDirty());
225
    }
226
227
    /**
228
     * @group 6613
229
     * @group 6614
230
     * @group 6616
231
     */
232
    public function testWillNotMarkCollectionAsDirtyAfterInitializationIfNoElementsWereAdded() : void
233
    {
234
        /* @var $unitOfWork UnitOfWork|\PHPUnit_Framework_MockObject_MockObject */
235
        $unitOfWork = $this->createMock(UnitOfWork::class);
236
237
        $this->_emMock->setUnitOfWork($unitOfWork);
238
239
        $newElementThatIsAlsoPersisted = new \stdClass();
240
        $persistedElement              = new \stdClass();
241
242
        $this->collection->add($newElementThatIsAlsoPersisted);
243
244
        self::assertFalse($this->collection->isInitialized());
245
        self::assertTrue($this->collection->isDirty());
246
247
        $unitOfWork
248
            ->expects(self::once())
249
            ->method('loadCollection')
250
            ->with($this->collection)
251
            ->willReturnCallback(function (PersistentCollection $persistentCollection) use (
252
                $persistedElement,
253
                $newElementThatIsAlsoPersisted
254
            ) : void {
255
                $persistentCollection->unwrap()->add($newElementThatIsAlsoPersisted);
256
                $persistentCollection->unwrap()->add($persistedElement);
257
            });
258
259
        $this->collection->initialize();
260
261
        self::assertSame(
262
            [$newElementThatIsAlsoPersisted, $persistedElement],
263
            $this->collection->toArray()
264
        );
265
        self::assertTrue($this->collection->isInitialized());
266
        self::assertFalse($this->collection->isDirty());
267
    }
268
269
    public function testModifyUOWForDeferredImplicitOwnerOnClear() : void
270
    {
271
        $unitOfWork = $this->createMock(UnitOfWork::class);
272
        $unitOfWork->expects(self::once())->method('scheduleCollectionDeletion');
273
        $this->_emMock->setUnitOfWork($unitOfWork);
274
275
        $this->collection->clear();
276
    }
277
}
278