Commit 96177e3e authored by zYne's avatar zYne

Added unit tests to cover all eventlistener events, fixed fatal transaction bug

parent 0a8123cf
...@@ -45,7 +45,7 @@ abstract class Doctrine_Configurable { ...@@ -45,7 +45,7 @@ abstract class Doctrine_Configurable {
* @param mixed $value * @param mixed $value
* @return void * @return void
*/ */
final public function setAttribute($attribute,$value) { public function setAttribute($attribute,$value) {
switch($attribute): switch($attribute):
case Doctrine::ATTR_BATCH_SIZE: case Doctrine::ATTR_BATCH_SIZE:
if($value < 0) if($value < 0)
...@@ -126,13 +126,51 @@ abstract class Doctrine_Configurable { ...@@ -126,13 +126,51 @@ abstract class Doctrine_Configurable {
* @param Doctrine_EventListener $listener * @param Doctrine_EventListener $listener
* @return void * @return void
*/ */
final public function setEventListener($listener) { public function setEventListener($listener) {
$i = Doctrine::ATTR_LISTENER; return $this->setListener($listener);
if( ! ($listener instanceof Doctrine_EventListener) && }
! ($listener instanceof Doctrine_EventListener_Chain)) /**
throw new Doctrine_Exception("EventListener must extend Doctrine_EventListener or Doctrine_EventListener_Chain"); * addListener
*
* @param Doctrine_DB_EventListener_Interface|Doctrine_Overloadable $listener
* @return Doctrine_DB
*/
public function addListener($listener, $name = null) {
if( ! ($this->attributes[Doctrine::ATTR_LISTENER] instanceof Doctrine_EventListener_Chain))
$this->attributes[Doctrine::ATTR_LISTENER] = new Doctrine_EventListener_Chain();
$this->attributes[Doctrine::ATTR_LISTENER]->add($listener, $name);
return $this;
}
/**
* getListener
*
* @return Doctrine_DB_EventListener_Interface|Doctrine_Overloadable
*/
public function getListener() {
if( ! isset($this->attributes[Doctrine::ATTR_LISTENER])) {
if(isset($this->parent))
return $this->parent->getListener();
return null;
}
return $this->attributes[Doctrine::ATTR_LISTENER];
}
/**
* setListener
*
* @param Doctrine_DB_EventListener_Interface|Doctrine_Overloadable $listener
* @return Doctrine_DB
*/
public function setListener($listener) {
if( ! ($listener instanceof Doctrine_EventListener_Interface) &&
! ($listener instanceof Doctrine_Overloadable))
throw new Doctrine_DB_Exception("Couldn't set eventlistener. EventListeners should implement either Doctrine_EventListener_Interface or Doctrine_Overloadable");
$this->attributes[Doctrine::ATTR_LISTENER] = $listener;
$this->attributes[$i] = $listener; return $this;
} }
/** /**
* returns the value of an attribute * returns the value of an attribute
...@@ -140,7 +178,7 @@ abstract class Doctrine_Configurable { ...@@ -140,7 +178,7 @@ abstract class Doctrine_Configurable {
* @param integer $attribute * @param integer $attribute
* @return mixed * @return mixed
*/ */
final public function getAttribute($attribute) { public function getAttribute($attribute) {
$attribute = (int) $attribute; $attribute = (int) $attribute;
if($attribute < 1 || $attribute > 17) if($attribute < 1 || $attribute > 17)
...@@ -160,7 +198,7 @@ abstract class Doctrine_Configurable { ...@@ -160,7 +198,7 @@ abstract class Doctrine_Configurable {
* *
* @return array * @return array
*/ */
final public function getAttributes() { public function getAttributes() {
return $this->attributes; return $this->attributes;
} }
/** /**
...@@ -170,7 +208,7 @@ abstract class Doctrine_Configurable { ...@@ -170,7 +208,7 @@ abstract class Doctrine_Configurable {
* @param Doctrine_Configurable $component * @param Doctrine_Configurable $component
* @return void * @return void
*/ */
final public function setParent(Doctrine_Configurable $component) { public function setParent(Doctrine_Configurable $component) {
$this->parent = $component; $this->parent = $component;
} }
/** /**
...@@ -179,7 +217,7 @@ abstract class Doctrine_Configurable { ...@@ -179,7 +217,7 @@ abstract class Doctrine_Configurable {
* *
* @return Doctrine_Configurable * @return Doctrine_Configurable
*/ */
final public function getParent() { public function getParent() {
return $this->parent; return $this->parent;
} }
} }
......
...@@ -155,8 +155,13 @@ class Doctrine_Connection_Transaction implements Countable, IteratorAggregate { ...@@ -155,8 +155,13 @@ class Doctrine_Connection_Transaction implements Countable, IteratorAggregate {
$this->bulkUpdate(); $this->bulkUpdate();
$this->bulkDelete(); $this->bulkDelete();
if($this->conn->getAttribute(Doctrine::ATTR_VLD)) { } catch(Exception $e) {
$this->rollback();
throw new Doctrine_Exception($e->__toString());
}
if($this->conn->getAttribute(Doctrine::ATTR_VLD)) {
if($this->validator->hasErrors()) { if($this->validator->hasErrors()) {
$this->rollback(); $this->rollback();
throw new Doctrine_Validator_Exception($this->validator); throw new Doctrine_Validator_Exception($this->validator);
...@@ -165,17 +170,9 @@ class Doctrine_Connection_Transaction implements Countable, IteratorAggregate { ...@@ -165,17 +170,9 @@ class Doctrine_Connection_Transaction implements Countable, IteratorAggregate {
$this->conn->getDBH()->commit(); $this->conn->getDBH()->commit();
} catch(PDOException $e) {
$this->rollback();
throw new Doctrine_Exception($e->__toString());
}
$this->conn->getAttribute(Doctrine::ATTR_LISTENER)->onTransactionCommit($this->conn); $this->conn->getAttribute(Doctrine::ATTR_LISTENER)->onTransactionCommit($this->conn);
$this->delete = array();
$this->state = Doctrine_Connection_Transaction::STATE_OPEN; $this->state = Doctrine_Connection_Transaction::STATE_OPEN;
$this->validator = null; $this->validator = null;
} elseif($this->transaction_level == 1) } elseif($this->transaction_level == 1)
...@@ -193,6 +190,10 @@ class Doctrine_Connection_Transaction implements Countable, IteratorAggregate { ...@@ -193,6 +190,10 @@ class Doctrine_Connection_Transaction implements Countable, IteratorAggregate {
public function rollback() { public function rollback() {
$this->conn->getAttribute(Doctrine::ATTR_LISTENER)->onPreTransactionRollback($this->conn); $this->conn->getAttribute(Doctrine::ATTR_LISTENER)->onPreTransactionRollback($this->conn);
$this->delete = array();
$this->insert = array();
$this->update = array();
$this->transaction_level = 0; $this->transaction_level = 0;
$this->conn->getDBH()->rollback(); $this->conn->getDBH()->rollback();
$this->state = Doctrine_Connection_Transaction::STATE_OPEN; $this->state = Doctrine_Connection_Transaction::STATE_OPEN;
...@@ -295,12 +296,18 @@ class Doctrine_Connection_Transaction implements Countable, IteratorAggregate { ...@@ -295,12 +296,18 @@ class Doctrine_Connection_Transaction implements Countable, IteratorAggregate {
$record->assignIdentifier(false); $record->assignIdentifier(false);
} }
if($record instanceof Doctrine_Record) { if($record instanceof Doctrine_Record) {
$table = $record->getTable(); $table = $record->getTable();
$table->getListener()->onPreDelete($record);
$params = substr(str_repeat("?, ",count($ids)),0,-2); $params = substr(str_repeat("?, ",count($ids)),0,-2);
$query = "DELETE FROM ".$record->getTable()->getTableName()." WHERE ".$table->getIdentifier()." IN(".$params.")"; $query = "DELETE FROM ".$record->getTable()->getTableName()." WHERE ".$table->getIdentifier()." IN(".$params.")";
$this->conn->execute($query,$ids); $this->conn->execute($query,$ids);
$table->getListener()->onDelete($record);
} }
} }
$this->delete = array(); $this->delete = array();
} }
......
...@@ -80,6 +80,3 @@ abstract class Doctrine_EventListener implements Doctrine_EventListener_Interfac ...@@ -80,6 +80,3 @@ abstract class Doctrine_EventListener implements Doctrine_EventListener_Interfac
public function onCollectionDelete(Doctrine_Collection $collection) { } public function onCollectionDelete(Doctrine_Collection $collection) { }
public function onPreCollectionDelete(Doctrine_Collection $collection) { } public function onPreCollectionDelete(Doctrine_Collection $collection) { }
} }
...@@ -167,12 +167,14 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite ...@@ -167,12 +167,14 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
// listen the onPreCreate event // listen the onPreCreate event
$this->table->getAttribute(Doctrine::ATTR_LISTENER)->onPreCreate($this); $this->table->getAttribute(Doctrine::ATTR_LISTENER)->onPreCreate($this);
} else { } else {
// listen the onPreLoad event // listen the onPreLoad event
$this->table->getAttribute(Doctrine::ATTR_LISTENER)->onPreLoad($this); $this->table->getAttribute(Doctrine::ATTR_LISTENER)->onPreLoad($this);
} }
// get the data array // get the data array
$this->data = $this->table->getData(); $this->data = $this->table->getData();
// get the column count // get the column count
$count = count($this->data); $count = count($this->data);
......
<?php <?php
require_once("UnitTestCase.php"); require_once("UnitTestCase.php");
class EventListenerClainTest extends Doctrine_Record { class EventListenerChainTest extends Doctrine_Record {
public function setTableDefinition() { public function setTableDefinition() {
$this->hasColumn("name", "string", 100); $this->hasColumn("name", "string", 100);
} }
...@@ -23,7 +23,7 @@ class Doctrine_EventListener_TestB extends Doctrine_EventListener { ...@@ -23,7 +23,7 @@ class Doctrine_EventListener_TestB extends Doctrine_EventListener {
} }
} }
class Doctrine_EventListenerChainTestCase extends Doctrine_UnitTestCase { class Doctrine_EventListener_Chain_TestCase extends Doctrine_UnitTestCase {
public function testEvents() { public function testEvents() {
$connection = $this->manager->openConnection(Doctrine_DB::getConn("sqlite::memory:")); $connection = $this->manager->openConnection(Doctrine_DB::getConn("sqlite::memory:"));
$debug = $this->listener->getMessages(); $debug = $this->listener->getMessages();
......
...@@ -15,15 +15,30 @@ class EventListenerTest extends Doctrine_Record { ...@@ -15,15 +15,30 @@ class EventListenerTest extends Doctrine_Record {
return md5($password); return md5($password);
} }
} }
class Doctrine_EventListener_TestLogger implements Doctrine_Overloadable, Countable {
private $messages = array();
class Doctrine_EventListenerTestCase extends Doctrine_UnitTestCase { public function __call($m, $a) {
public function testEvents() {
$connection = $this->manager->openConnection(Doctrine_DB::getConn("sqlite::memory:")); $this->messages[] = $m;
$debug = $this->listener->getMessages(); }
$last = end($debug); public function pop() {
$this->assertTrue($last->getObject() instanceof Doctrine_Connection); return array_pop($this->messages);
$this->assertTrue($last->getCode() == Doctrine_EventListener_Debugger::EVENT_OPEN); }
public function clear() {
$this->messages = array();
} }
public function getAll() {
return $this->messages;
}
public function count() {
return count($this->messages);
}
}
class Doctrine_EventListenerTestCase extends Doctrine_UnitTestCase {
private $logger;
public function testAccessorInvoker() { public function testAccessorInvoker() {
$e = new EventListenerTest; $e = new EventListenerTest;
$e->name = "something"; $e->name = "something";
...@@ -61,7 +76,127 @@ class Doctrine_EventListenerTestCase extends Doctrine_UnitTestCase { ...@@ -61,7 +76,127 @@ class Doctrine_EventListenerTestCase extends Doctrine_UnitTestCase {
$this->assertEqual($e->name, 'SOMETHING'); $this->assertEqual($e->name, 'SOMETHING');
$this->assertEqual($e->rawGet('name'), 'something'); $this->assertEqual($e->rawGet('name'), 'something');
$this->assertEqual($e->password, '202cb962ac59075b964b07152d234b70'); $this->assertEqual($e->password, '202cb962ac59075b964b07152d234b70');
}
public function testSetListener() {
$this->logger = new Doctrine_EventListener_TestLogger();
$e = new EventListenerTest;
$e->getTable()->setListener($this->logger);
$this->assertEqual($e->getTable()->getListener(), $this->logger);
} }
public function testOnLoad() {
$this->logger->clear();
$this->assertEqual($this->connection->getTable('EventListenerTest')->getListener(), $this->logger);
$this->connection->clear();
$e = $this->connection->getTable('EventListenerTest')->find(1);
$this->assertEqual($e->getTable()->getListener(), $this->logger);
$this->assertEqual($this->logger->pop(), 'onLoad');
$this->assertEqual($this->logger->pop(), 'onPreLoad');
}
public function testOnCreate() {
$e = new EventListenerTest;
$e->setListener($this->logger);
$this->logger->clear();
$e = new EventListenerTest;
$this->assertEqual($this->logger->pop(), 'onCreate');
$this->assertEqual($this->logger->pop(), 'onPreCreate');
$this->assertEqual($this->logger->count(), 0);
}
public function testOnSleepAndOnWakeUp() {
$e = new EventListenerTest;
$this->logger->clear();
$s = serialize($e);
$this->assertEqual($this->logger->pop(), 'onSleep');
$this->assertEqual($this->logger->count(), 0);
$e = unserialize($s);
$this->assertEqual($this->logger->pop(), 'onWakeUp');
$this->assertEqual($this->logger->count(), 0);
}
public function testTransaction() {
$e = new EventListenerTest();
$e->name = "test 1";
$this->logger->clear();
$e->save();
$this->assertEqual($this->logger->pop(), 'onSave');
$this->assertEqual($this->logger->pop(), 'onInsert');
$this->assertEqual($this->logger->pop(), 'onPreInsert');
$this->assertEqual($this->logger->pop(), 'onPreSave');
$e->name = "test 2";
$e->save();
$this->assertEqual($this->logger->pop(), 'onSave');
$this->assertEqual($this->logger->pop(), 'onUpdate');
$this->assertEqual($this->logger->pop(), 'onPreUpdate');
$this->assertEqual($this->logger->pop(), 'onPreSave');
$this->logger->clear();
$e->delete();
$this->assertEqual($this->logger->pop(), 'onDelete');
$this->assertEqual($this->logger->pop(), 'onPreDelete');
}
public function testTransactionWithConnectionListener() {
$e = new EventListenerTest();
$e->getTable()->getConnection()->setListener($this->logger);
$e->name = "test 2";
$this->logger->clear();
$e->save();
$this->assertEqual($this->logger->pop(), 'onTransactionCommit');
$this->assertEqual($this->logger->pop(), 'onSave');
$this->assertEqual($this->logger->pop(), 'onInsert');
$this->assertEqual($this->logger->pop(), 'onPreInsert');
$this->assertEqual($this->logger->pop(), 'onPreSave');
$this->assertEqual($this->logger->pop(), 'onTransactionBegin');
$this->assertEqual($this->logger->pop(), 'onPreTransactionBegin');
$e->name = "test 1";
$e->save();
$this->assertEqual($this->logger->pop(), 'onTransactionCommit');
$this->assertEqual($this->logger->pop(), 'onSave');
$this->assertEqual($this->logger->pop(), 'onUpdate');
$this->assertEqual($this->logger->pop(), 'onPreUpdate');
$this->assertEqual($this->logger->pop(), 'onPreSave');
$this->assertEqual($this->logger->pop(), 'onTransactionBegin');
$this->assertEqual($this->logger->pop(), 'onPreTransactionBegin');
$this->logger->clear();
$e->delete();
$this->assertEqual($this->logger->pop(), 'onTransactionCommit');
$this->assertEqual($this->logger->pop(), 'onDelete');
$this->assertEqual($this->logger->pop(), 'onPreDelete');
$this->assertEqual($this->logger->pop(), 'onTransactionBegin');
$this->assertEqual($this->logger->pop(), 'onPreTransactionBegin');
}
public function prepareData() { } public function prepareData() { }
public function prepareTables() { public function prepareTables() {
$this->tables = array('EventListenerTest'); $this->tables = array('EventListenerTest');
......
...@@ -9,6 +9,20 @@ class Doctrine_RecordTestCase extends Doctrine_UnitTestCase { ...@@ -9,6 +9,20 @@ class Doctrine_RecordTestCase extends Doctrine_UnitTestCase {
$this->tables[] = "GzipTest"; $this->tables[] = "GzipTest";
parent::prepareTables(); parent::prepareTables();
} }
public function testNotNullConstraint() {
$null = new NotNullTest();
$null->name = null;
$null->type = 1;
try {
$null->save();
$this->fail();
} catch(Doctrine_Exception $e) {
$this->pass();
}
}
public function testGzipType() { public function testGzipType() {
$gzip = new GzipTest(); $gzip = new GzipTest();
$gzip->gzip = "compressed"; $gzip->gzip = "compressed";
......
...@@ -453,6 +453,12 @@ class Data_File extends Doctrine_Record { ...@@ -453,6 +453,12 @@ class Data_File extends Doctrine_Record {
$this->hasOne("File_Owner", "Data_File.file_owner_id"); $this->hasOne("File_Owner", "Data_File.file_owner_id");
} }
} }
class NotNullTest extends Doctrine_Record {
public function setTableDefinition() {
$this->hasColumn("name", "string", 100, "notnull");
$this->hasColumn("type", "integer", 11);
}
}
class File_Owner extends Doctrine_Record { class File_Owner extends Doctrine_Record {
public function setTableDefinition() { public function setTableDefinition() {
$this->hasColumn("name", "string", 255); $this->hasColumn("name", "string", 255);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment