From c45823aa49257bb287fa868515d459a4630cd583 Mon Sep 17 00:00:00 2001 From: zYne Date: Mon, 25 Jun 2007 18:47:36 +0000 Subject: [PATCH] new transaction tests --- lib/Doctrine/Transaction.php | 46 +++++--- tests/TransactionTestCase.php | 213 ++++++++++++++++++++++++++++++---- 2 files changed, 226 insertions(+), 33 deletions(-) diff --git a/lib/Doctrine/Transaction.php b/lib/Doctrine/Transaction.php index 568f54600..c8b51b8b0 100644 --- a/lib/Doctrine/Transaction.php +++ b/lib/Doctrine/Transaction.php @@ -197,6 +197,18 @@ class Doctrine_Transaction extends Doctrine_Connection_Module { return $this->transactionLevel; } + /** + * getTransactionLevel + * set the current transaction nesting level + * + * @return Doctrine_Transaction this object + */ + public function setTransactionLevel($level) + { + $this->transactionLevel = $level; + + return $this; + } /** * beginTransaction * Start a transaction or set a savepoint. @@ -215,10 +227,8 @@ class Doctrine_Transaction extends Doctrine_Connection_Module $this->conn->connect(); $listener = $this->conn->getAttribute(Doctrine::ATTR_LISTENER); - - if ( ! is_null($savepoint)) { - $this->beginTransaction(); + if ( ! is_null($savepoint)) { $this->savePoints[] = $savepoint; $event = new Doctrine_Event($this, Doctrine_Event::SAVEPOINT_CREATE); @@ -275,7 +285,7 @@ class Doctrine_Transaction extends Doctrine_Connection_Module $listener = $this->conn->getAttribute(Doctrine::ATTR_LISTENER); if ( ! is_null($savepoint)) { - $this->transactionLevel = $this->removeSavePoints($savepoint); + $this->transactionLevel -= $this->removeSavePoints($savepoint); $event = new Doctrine_Event($this, Doctrine_Event::SAVEPOINT_COMMIT); @@ -323,10 +333,10 @@ class Doctrine_Transaction extends Doctrine_Connection_Module $listener->postTransactionCommit($event); } + + $this->transactionLevel--; } - $this->transactionLevel--; - return true; } /** @@ -354,7 +364,7 @@ class Doctrine_Transaction extends Doctrine_Connection_Module $listener = $this->conn->getAttribute(Doctrine::ATTR_LISTENER); if ( ! is_null($savepoint)) { - $this->transactionLevel = $this->removeSavePoints($savepoint); + $this->transactionLevel -= $this->removeSavePoints($savepoint); $event = new Doctrine_Event($this, Doctrine_Event::SAVEPOINT_ROLLBACK); @@ -425,18 +435,28 @@ class Doctrine_Transaction extends Doctrine_Connection_Module * and all its children savepoints * * @param sring $savepoint name of the savepoint to remove - * @return integer the current transaction level + * @return integer removed savepoints */ private function removeSavePoints($savepoint) { - $i = array_search($savepoint, $this->savePoints); + $this->savePoints = array_values($this->savePoints); - $c = count($this->savePoints); + $found = false; + $i = 0; - for ($x = $i; $x < count($this->savePoints); $x++) { - unset($this->savePoints[$x]); + foreach ($this->savePoints as $key => $sp) { + if ( ! $found) { + if ($sp === $savepoint) { + $found = true; + } + } + if ($found) { + $i++; + unset($this->savePoints[$key]); + } } - return ($c - $i); + + return $i; } /** * setIsolation diff --git a/tests/TransactionTestCase.php b/tests/TransactionTestCase.php index b61bcf3f6..39738a271 100644 --- a/tests/TransactionTestCase.php +++ b/tests/TransactionTestCase.php @@ -34,36 +34,118 @@ class Doctrine_Transaction_TestCase extends Doctrine_UnitTestCase { public function testInit() { - $this->transaction = new Doctrine_Transaction_Mock(); + $this->transaction = new Doctrine_Transaction_Mock(); + + $this->listener = new TransactionListener(); + + $this->conn->setListener($this->listener); } - public function testCreateSavepointIsOnlyImplementedAtDriverLevel() { + + public function testCreateSavepointListenersGetInvoked() + { try { $this->transaction->beginTransaction('point'); - $this->fail(); - } catch(Doctrine_Transaction_Exception $e) { + $this->pass(); + } catch(Doctrine_Transaction_Exception $e) { + $this->fail(); } + + $this->assertEqual($this->listener->pop(), 'postSavepointCreate'); + $this->assertEqual($this->listener->pop(), 'preSavepointCreate'); } - public function testReleaseSavepointIsOnlyImplementedAtDriverLevel() { + + public function testCommitSavepointListenersGetInvoked() + { try { $this->transaction->commit('point'); - $this->fail(); - } catch(Doctrine_Transaction_Exception $e) { + $this->pass(); + } catch(Doctrine_Transaction_Exception $e) { + $this->fail(); } + + $this->assertEqual($this->listener->pop(), 'postSavepointCommit'); + $this->assertEqual($this->listener->pop(), 'preSavepointCommit'); + $this->assertEqual($this->transaction->getTransactionLevel(), 0); } - public function testRollbackSavepointIsOnlyImplementedAtDriverLevel() { + public function testNestedSavepoints() + { + $this->assertEqual($this->transaction->getTransactionLevel(), 0); + $this->transaction->beginTransaction(); + $this->assertEqual($this->transaction->getTransactionLevel(), 1); + $this->transaction->beginTransaction('point 1'); + $this->assertEqual($this->transaction->getTransactionLevel(), 2); + $this->transaction->beginTransaction('point 2'); + $this->assertEqual($this->transaction->getTransactionLevel(), 3); + $this->transaction->commit('point 2'); + $this->assertEqual($this->transaction->getTransactionLevel(), 2); + $this->transaction->commit('point 1'); + $this->assertEqual($this->transaction->getTransactionLevel(), 1); + $this->transaction->commit(); + $this->assertEqual($this->transaction->getTransactionLevel(), 0); + } + + public function testRollbackSavepointListenersGetInvoked() + { try { - $this->transaction->beginTransaction(); - + $this->transaction->beginTransaction('point'); $this->transaction->rollback('point'); + + $this->pass(); + } catch(Doctrine_Transaction_Exception $e) { + $this->fail(); + } + + $this->assertEqual($this->listener->pop(), 'postSavepointRollback'); + $this->assertEqual($this->listener->pop(), 'preSavepointRollback'); + $this->assertEqual($this->listener->pop(), 'postSavepointCreate'); + $this->assertEqual($this->listener->pop(), 'preSavepointCreate'); + $this->assertEqual($this->transaction->getTransactionLevel(), 0); + + $this->listener = new Doctrine_Eventlistener(); + $this->conn->setListener($this->listener); + } + + public function testCreateSavepointIsOnlyImplementedAtDriverLevel() + { + try { + $this->transaction->beginTransaction('savepoint'); $this->fail(); } catch(Doctrine_Transaction_Exception $e) { $this->pass(); } } - public function testSetIsolationIsOnlyImplementedAtDriverLevel() { + + public function testReleaseSavepointIsOnlyImplementedAtDriverLevel() + { + try { + $this->transaction->setTransactionLevel(1); + + $this->transaction->commit('savepoint'); + $this->fail(); + } catch(Doctrine_Transaction_Exception $e) { + $this->pass(); + } + $this->transaction->setTransactionLevel(0); + } + + public function testRollbackSavepointIsOnlyImplementedAtDriverLevel() + { + try { + $this->transaction->setTransactionLevel(1); + + $this->transaction->rollback('savepoint'); + $this->fail(); + } catch(Doctrine_Transaction_Exception $e) { + $this->pass(); + } + $this->transaction->setTransactionLevel(0); + } + + public function testSetIsolationIsOnlyImplementedAtDriverLevel() + { try { $this->transaction->setIsolation('READ UNCOMMITTED'); $this->fail(); @@ -71,7 +153,9 @@ class Doctrine_Transaction_TestCase extends Doctrine_UnitTestCase $this->pass(); } } - public function testGetIsolationIsOnlyImplementedAtDriverLevel() { + + public function testGetIsolationIsOnlyImplementedAtDriverLevel() + { try { $this->transaction->GetIsolation('READ UNCOMMITTED'); $this->fail(); @@ -79,27 +163,116 @@ class Doctrine_Transaction_TestCase extends Doctrine_UnitTestCase $this->pass(); } } - public function testTransactionLevelIsInitiallyZero() { + + public function testTransactionLevelIsInitiallyZero() + { $this->assertEqual($this->transaction->getTransactionLevel(), 0); } - public function testGetStateReturnsStateConstant() { - $this->assertEqual($this->transaction->getState(), Doctrine_Transaction::STATE_SLEEP); + + public function testGetStateReturnsStateConstant() + { + $this->assertEqual($this->transaction->getState(), Doctrine_Transaction::STATE_SLEEP); } - public function testCommittingNotActiveTransactionReturnsFalse() { + + public function testCommittingNotActiveTransactionReturnsFalse() + { $this->assertEqual($this->transaction->commit(), false); } - public function testExceptionIsThrownWhenUsingRollbackOnNotActiveTransaction() { + + public function testExceptionIsThrownWhenUsingRollbackOnNotActiveTransaction() + { $this->assertEqual($this->transaction->rollback(), false); } - public function testBeginTransactionStartsNewTransaction() { + + public function testBeginTransactionStartsNewTransaction() + { $this->transaction->beginTransaction(); - $this->assertEqual($this->adapter->pop(), 'BEGIN TRANSACTION'); + $this->assertEqual($this->adapter->pop(), 'BEGIN TRANSACTION'); } - public function testCommitMethodCommitsCurrentTransaction() { + + public function testCommitMethodCommitsCurrentTransaction() + { $this->transaction->commit(); $this->assertEqual($this->adapter->pop(), 'COMMIT'); } } +class TransactionListener extends Doctrine_EventListener +{ + protected $_messages = array(); + + public function preTransactionCommit(Doctrine_Event $event) + { + $this->_messages[] = __FUNCTION__; + + $event->skipOperation(); + } + public function postTransactionCommit(Doctrine_Event $event) + { + $this->_messages[] = __FUNCTION__; + } + + public function preTransactionRollback(Doctrine_Event $event) + { + $this->_messages[] = __FUNCTION__; + + $event->skipOperation(); + } + public function postTransactionRollback(Doctrine_Event $event) + { + $this->_messages[] = __FUNCTION__; + } + + public function preTransactionBegin(Doctrine_Event $event) + { + $this->_messages[] = __FUNCTION__; + + $event->skipOperation(); + } + public function postTransactionBegin(Doctrine_Event $event) + { + $this->_messages[] = __FUNCTION__; + } + + + public function preSavepointCommit(Doctrine_Event $event) + { + $this->_messages[] = __FUNCTION__; + + $event->skipOperation(); + } + public function postSavepointCommit(Doctrine_Event $event) + { + $this->_messages[] = __FUNCTION__; + } + + public function preSavepointRollback(Doctrine_Event $event) + { + $this->_messages[] = __FUNCTION__; + + $event->skipOperation(); + } + public function postSavepointRollback(Doctrine_Event $event) + { + $this->_messages[] = __FUNCTION__; + } + + public function preSavepointCreate(Doctrine_Event $event) + { + $this->_messages[] = __FUNCTION__; + + $event->skipOperation(); + } + + public function postSavepointCreate(Doctrine_Event $event) + { + $this->_messages[] = __FUNCTION__; + } + + public function pop() + { + return array_pop($this->_messages); + } +}