UnitOfWorkTest.php 8.04 KB
Newer Older
1
<?php
romanb's avatar
romanb committed
2

3
namespace Doctrine\Tests\ORM;
romanb's avatar
romanb committed
4

5 6 7 8 9 10 11 12
use Doctrine\Tests\Mocks\ConnectionMock;
use Doctrine\Tests\Mocks\EntityManagerMock;
use Doctrine\Tests\Mocks\UnitOfWorkMock;
use Doctrine\Tests\Mocks\EntityPersisterMock;
use Doctrine\Tests\Mocks\IdentityIdGeneratorMock;
use Doctrine\Tests\Models\Forum\ForumUser;
use Doctrine\Tests\Models\Forum\ForumAvatar;

13
require_once __DIR__ . '/../TestInit.php';
14

15 16 17
/**
 * UnitOfWork tests.
 */
18
class UnitOfWorkTest extends \Doctrine\Tests\OrmTestCase
19
{
romanb's avatar
romanb committed
20
    // SUT
21
    private $_unitOfWork;
22 23
    // Provides a sequence mock to the UnitOfWork
    private $_connectionMock;
romanb's avatar
romanb committed
24
    // The EntityManager mock that provides the mock persisters
25 26
    private $_emMock;
    
27 28
    protected function setUp() {
        parent::setUp();
29
        $this->_connectionMock = new ConnectionMock(array(), new \Doctrine\Tests\Mocks\DriverMock());
30
        $this->_emMock = EntityManagerMock::create($this->_connectionMock);
romanb's avatar
romanb committed
31
        // SUT
32
        $this->_unitOfWork = new UnitOfWorkMock($this->_emMock);
33
        $this->_emMock->setUnitOfWork($this->_unitOfWork);
34 35 36 37 38
    }
    
    protected function tearDown() {
    }
    
39
    public function testRegisterRemovedOnNewEntityIsIgnored()
40
    {
41 42
        $user = new ForumUser();
        $user->username = 'romanb';
romanb's avatar
romanb committed
43 44 45
        $this->assertFalse($this->_unitOfWork->isScheduledForDelete($user));
        $this->_unitOfWork->scheduleForDelete($user);
        $this->assertFalse($this->_unitOfWork->isScheduledForDelete($user));        
46 47
    }
    
48 49 50 51
    
    /* Operational tests */
    
    public function testSavingSingleEntityWithIdentityColumnForcesInsert()
52 53
    {
        // Setup fake persister and id generator for identity generation
54
        $userPersister = new EntityPersisterMock($this->_emMock, $this->_emMock->getClassMetadata("Doctrine\Tests\Models\Forum\ForumUser"));
55
        $this->_unitOfWork->setEntityPersister('Doctrine\Tests\Models\Forum\ForumUser', $userPersister);
56 57
        //$idGeneratorMock = new IdentityIdGeneratorMock($this->_emMock);
        //$this->_emMock->setIdGenerator('Doctrine\Tests\Models\Forum\ForumUser', $idGeneratorMock);
58
        $userPersister->setMockIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_IDENTITY);
59 60 61 62

        // Test
        $user = new ForumUser();
        $user->username = 'romanb';
romanb's avatar
romanb committed
63
        $this->_unitOfWork->persist($user);
64 65

        // Check
romanb's avatar
romanb committed
66
        $this->assertEquals(0, count($userPersister->getInserts()));
67 68
        $this->assertEquals(0, count($userPersister->getUpdates()));
        $this->assertEquals(0, count($userPersister->getDeletes()));   
romanb's avatar
romanb committed
69
        $this->assertFalse($this->_unitOfWork->isInIdentityMap($user));
70
        // should no longer be scheduled for insert
romanb's avatar
romanb committed
71
        $this->assertTrue($this->_unitOfWork->isScheduledForInsert($user));
72
        
73
        // Now lets check whether a subsequent commit() does anything
74 75 76
        $userPersister->reset();

        // Test
romanb's avatar
romanb committed
77
        $this->_unitOfWork->commit();
78
        
romanb's avatar
romanb committed
79 80
        // Check.
        $this->assertEquals(1, count($userPersister->getInserts()));
81 82
        $this->assertEquals(0, count($userPersister->getUpdates()));
        $this->assertEquals(0, count($userPersister->getDeletes()));
romanb's avatar
romanb committed
83 84 85
        
        // should have an id
        $this->assertTrue(is_numeric($user->id));
86
    }
87 88 89 90 91 92

    /**
     * Tests a scenario where a save() operation is cascaded from a ForumUser
     * to its associated ForumAvatar, both entities using IDENTITY id generation.
     */
    public function testCascadedIdentityColumnInsert()
93
    {
94 95
        // Setup fake persister and id generator for identity generation
        //ForumUser
96
        $userPersister = new EntityPersisterMock($this->_emMock, $this->_emMock->getClassMetadata("Doctrine\Tests\Models\Forum\ForumUser"));
97
        $this->_unitOfWork->setEntityPersister('Doctrine\Tests\Models\Forum\ForumUser', $userPersister);
98 99
        //$userIdGeneratorMock = new IdentityIdGeneratorMock($this->_emMock);
        //$this->_emMock->setIdGenerator('Doctrine\Tests\Models\Forum\ForumUser', $userIdGeneratorMock);
100
        $userPersister->setMockIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_IDENTITY);
101
        // ForumAvatar
102
        $avatarPersister = new EntityPersisterMock($this->_emMock, $this->_emMock->getClassMetadata("Doctrine\Tests\Models\Forum\ForumAvatar"));
103
        $this->_unitOfWork->setEntityPersister('Doctrine\Tests\Models\Forum\ForumAvatar', $avatarPersister);
104 105
        //$avatarIdGeneratorMock = new IdentityIdGeneratorMock($this->_emMock);
        //$this->_emMock->setIdGenerator('Doctrine\Tests\Models\Forum\ForumAvatar', $avatarIdGeneratorMock);
106
        $avatarPersister->setMockIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_IDENTITY);
107 108 109 110

        // Test
        $user = new ForumUser();
        $user->username = 'romanb';
111
        $avatar = new ForumAvatar();
112
        $user->avatar = $avatar;
romanb's avatar
romanb committed
113 114 115
        $this->_unitOfWork->persist($user); // save cascaded to avatar
        
        $this->_unitOfWork->commit();
116 117 118 119

        $this->assertTrue(is_numeric($user->id));
        $this->assertTrue(is_numeric($avatar->id));

romanb's avatar
romanb committed
120
        $this->assertEquals(1, count($userPersister->getInserts()));
121 122 123
        $this->assertEquals(0, count($userPersister->getUpdates()));
        $this->assertEquals(0, count($userPersister->getDeletes()));

romanb's avatar
romanb committed
124
        $this->assertEquals(1, count($avatarPersister->getInserts()));
125 126
        $this->assertEquals(0, count($avatarPersister->getUpdates()));
        $this->assertEquals(0, count($avatarPersister->getDeletes()));
127
    }
128

129
    public function testChangeTrackingNotify()
130
    {
131 132 133
        $persister = new EntityPersisterMock($this->_emMock, $this->_emMock->getClassMetadata("Doctrine\Tests\ORM\NotifyChangedEntity"));
        $this->_unitOfWork->setEntityPersister('Doctrine\Tests\ORM\NotifyChangedEntity', $persister);

134 135
        $entity = new NotifyChangedEntity;
        $entity->setData('thedata');
romanb's avatar
romanb committed
136 137 138
        $this->_unitOfWork->persist($entity);
        
        $this->_unitOfWork->commit();
139 140 141 142 143

        $this->assertTrue($this->_unitOfWork->isInIdentityMap($entity));

        $entity->setData('newdata');

romanb's avatar
romanb committed
144
        $this->assertTrue($this->_unitOfWork->isScheduledForUpdate($entity));
145 146

        $this->assertEquals(array('data' => array('thedata', 'newdata')), $this->_unitOfWork->getEntityChangeSet($entity));
147
    }
148

149
    /*
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
    public function testSavingSingleEntityWithSequenceIdGeneratorSchedulesInsert()
    {
        //...
    }
    
    public function testSavingSingleEntityWithTableIdGeneratorSchedulesInsert()
    {
        //...
    }
    
    public function testSavingSingleEntityWithSingleNaturalIdForcesInsert()
    {
        //...
    }
    
    public function testSavingSingleEntityWithCompositeIdForcesInsert()
    {
        //...
    }
    
    public function testSavingEntityGraphWithIdentityColumnsForcesInserts()
    {
        //...
    }
    
    public function testSavingEntityGraphWithSequencesDelaysInserts()
    {
        //...
    }
    
    public function testSavingEntityGraphWithNaturalIdsForcesInserts()
    {
        //...
    }
    
    public function testSavingEntityGraphWithMixedIdGenerationStrategies()
    {
        //...
    }
189
    */
190 191 192
}

/**
193
 * @Entity
194 195 196 197 198
 */
class NotifyChangedEntity implements \Doctrine\Common\NotifyPropertyChanged
{
    private $_listeners = array();
    /**
199 200
     * @Id
     * @Column(type="integer")
201
     * @GeneratedValue(strategy="AUTO")
202 203 204
     */
    private $id;
    /**
205
     * @Column(type="string")
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
     */
    private $data;

    public function getId() {
        return $this->id;
    }

    public function getData() {
        return $this->data;
    }

    public function setData($data) {
        if ($data != $this->data) {
            $this->_onPropertyChanged('data', $this->data, $data);
            $this->data = $data;
        }
    }

    public function addPropertyChangedListener(\Doctrine\Common\PropertyChangedListener $listener)
    {
        $this->_listeners[] = $listener;
    }

    protected function _onPropertyChanged($propName, $oldValue, $newValue) {
        if ($this->_listeners) {
            foreach ($this->_listeners as $listener) {
                $listener->propertyChanged($this, $propName, $oldValue, $newValue);
            }
        }
    }
236
}