Added ability to auto-fixturize models when testing controllers

git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@4874 3807eeeb-6ff5-0310-8944-8be069107fe0
This commit is contained in:
mariano.iglesias 2007-04-17 21:20:38 +00:00
parent 29cadf7460
commit 11d588ff15
2 changed files with 195 additions and 38 deletions

View file

@ -37,11 +37,26 @@ vendor('simpletest'.DS.'unit_tester');
*/ */
class CakeTestDispatcher extends Dispatcher { class CakeTestDispatcher extends Dispatcher {
var $controller; var $controller;
var $testCase;
function testCase(&$testCase) {
$this->testCase =& $testCase;
}
function _invoke (&$controller, $params, $missingAction = false) { function _invoke (&$controller, $params, $missingAction = false) {
$this->controller =& $controller; $this->controller =& $controller;
return parent::_invoke($this->controller, $params, $missingAction); if (isset($this->testCase) && method_exists($this->testCase, 'startController')) {
$this->testCase->startController($this->controller, $params);
}
$result = parent::_invoke($this->controller, $params, $missingAction);
if (isset($this->testCase) && method_exists($this->testCase, 'endController')) {
$this->testCase->endController($this->controller, $params);
}
return $result;
} }
} }
/** /**
@ -94,32 +109,141 @@ class CakeTestCase extends UnitTestCase {
*/ */
function endTest($method) { function endTest($method) {
} }
/**
* Callback issued when a controller's action is about to be invoked through requestAction().
*
* @param Controller $controller Controller that's about to be invoked.
* @param array $params Additional parameters as sent by requestAction().
*/
function startController(&$controller, $params = array()) {
if (isset($params['fixturize']) && ((is_array($params['fixturize']) && !empty($params['fixturize'])) || $params['fixturize'] === true)) {
if (!isset($this->db)) {
$this->_initDb();
}
$classRegistry =& ClassRegistry::getInstance();
$models = array();
foreach($classRegistry->__map as $key => $name) {
$object =& $classRegistry->getObject(Inflector::camelize($key));
if (is_subclass_of($object, 'Model') && ((is_array($params['fixturize']) && in_array($object->name, $params['fixturize'])) || $params['fixturize'] === true)) {
$models[$object->name] = array (
'table' => $object->table,
'model' => $object->name,
'key' => Inflector::camelize($key)
);
}
}
if (!empty($models) && isset($this->db)) {
$this->_queries = array(
'create' => array(),
'insert' => array(),
'drop' => array()
);
foreach($models as $model) {
$fixture =& new CakeTestFixture($this->db);
$fixture->name = $model['model'] . 'Test';
$fixture->table = $model['table'];
$fixture->import = array('model' => $model['model'], 'records' => true);
$fixture->init();
$createFixture = $fixture->create();
$insertsFixture = $fixture->insert();
$dropFixture = $fixture->drop();
if (!empty($createFixture)) {
$this->_queries['create'] = am($this->_queries['create'], array($createFixture));
}
if (!empty($insertsFixture)) {
$this->_queries['insert'] = am($this->_queries['insert'], $insertsFixture);
}
if (!empty($dropFixture)) {
$this->_queries['drop'] = am($this->_queries['drop'], array($dropFixture));
}
}
foreach($this->_queries['create'] as $query) {
if (isset($query) && $query !== false) {
$this->db->_execute($query);
}
}
foreach($this->_queries['insert'] as $query) {
if (isset($query) && $query !== false) {
$this->db->_execute($query);
}
}
foreach($models as $model) {
$object =& $classRegistry->getObject($model['key']);
if ($object !== false) {
$object->useDbConfig = 'test_suite';
$object->setSource($object->table);
}
}
}
}
}
/**
* Callback issued when a controller's action has been invoked through requestAction().
*
* @param Controller $controller Controller that has been invoked.
* * @param array $params Additional parameters as sent by requestAction().
*/
function endController(&$controller, $params = array()) {
if (isset($this->db) && isset($this->_queries) && !empty($this->_queries) && !empty($this->_queries['drop'])) {
foreach($this->_queries['drop'] as $query) {
if (isset($query) && $query !== false) {
$this->db->_execute($query);
}
}
}
}
/** /**
* Executes a Cake URL, optionally getting the view rendering or what is returned * Executes a Cake URL, optionally getting the view rendering or what is returned
* when params['requested'] is set. * when params['requested'] is set.
* *
* @param string $url Cake URL to execute (e.g: /articles/view/455) * @param string $url Cake URL to execute (e.g: /articles/view/455)
* @param string $return Set to what you want returned (result / render / vars) * @param array $params Parameters
* @param array $data Data that will be sent to controller. E.g: array('Article' => array('id'=>4))
* @param string $method Method to simulate posting of data to controller ('get' or 'post')
* *
* @return mixed What is returned from action (if $requested is true), or view rendered html * @return mixed What is returned from action (if $requested is true), or view rendered html
* *
* @access protected * @access protected
*/ */
function requestAction($url, $return = 'result', $data = null, $method = 'post') { function requestAction($url, $params = array()) {
if (is_array($data) && !empty($data)) { $default = array(
$data = array('data' => $data); 'return' => 'result',
'fixturize' => false,
'data' => array(),
'method' => 'post'
);
$params = am($default, $params);
if (!empty($params['data'])) {
$data = array('data' => $params['data']);
if (low($method) == 'get') { if (low($params['method']) == 'get') {
$_GET = $data; $_GET = $data;
} else { } else {
$_POST = $data; $_POST = $data;
} }
} }
$return = $params['return'];
unset($params['data']);
unset($params['method']);
unset($params['return']);
$dispatcher =& new CakeTestDispatcher(); $dispatcher =& new CakeTestDispatcher();
$params = array(); $dispatcher->testCase($this);
if (low($return) != 'result') { if (low($return) != 'result') {
$params['return'] = 0; $params['return'] = 0;
@ -129,10 +253,17 @@ class CakeTestCase extends UnitTestCase {
$result = ob_get_clean(); $result = ob_get_clean();
if (low($return) == 'vars') { if (low($return) == 'vars') {
$result = $dispatcher->controller->viewVars; $view =& ClassRegistry::getObject('view');
$viewVars = $view->getVars();
if (isset($dispatcher->controller->__viewClass) && !empty($dispatcher->controller->__viewClass->pageTitle)) { $result = array();
$result = am($result, array('title' => $dispatcher->controller->__viewClass->pageTitle));
foreach($viewVars as $var) {
$result[$var] = $view->getVar($var);
}
if (!empty($view->pageTitle)) {
$result = am($result, array('title' => $view->pageTitle));
} }
} }
} else { } else {
@ -143,6 +274,18 @@ class CakeTestCase extends UnitTestCase {
$result = @$dispatcher->dispatch($url, $params); $result = @$dispatcher->dispatch($url, $params);
} }
$classRegistry =& ClassRegistry::getInstance();
$keys = array_keys($classRegistry->__objects);
foreach($keys as $key) {
$key = Inflector::camelize($key);
$classRegistry->removeObject($key);
}
$classRegistry->__map = array();
if (isset($this->_queries)) {
unset($this->_queries);
}
return $result; return $result;
} }
/** /**
@ -161,27 +304,7 @@ class CakeTestCase extends UnitTestCase {
// Set up DB connection // Set up DB connection
if (isset($this->fixtures) && low($method) == 'start') { if (isset($this->fixtures) && low($method) == 'start') {
// Try for test DB $this->_initDb();
restore_error_handler();
@$db =& ConnectionManager::getDataSource('test');
set_error_handler('simpleTestErrorHandler');
// Try for default DB
if (!$db->isConnected()) {
$db =& ConnectionManager::getDataSource('default');
}
// Add test prefix
$config = $db->config;
$config['prefix'] .= 'test_suite_';
// Set up db connection
ConnectionManager::create('test_suite', $config);
// Get db connection
$this->db =& ConnectionManager::getDataSource('test_suite');
$this->db->fullDebug = false;
$this->_loadFixtures(); $this->_loadFixtures();
} }
@ -268,11 +391,37 @@ class CakeTestCase extends UnitTestCase {
* *
* @access public * @access public
*/ */
function getTests() { function getTests() {
$methods = am(am(array('start', 'startCase'), parent::getTests()), array('endCase', 'end')); $methods = am(am(array('start', 'startCase'), parent::getTests()), array('endCase', 'end'));
return $methods; return $methods;
} }
/**
* Initialize DB connection.
*
*/
function _initDb() {
// Try for test DB
restore_error_handler();
@$db =& ConnectionManager::getDataSource('test');
set_error_handler('simpleTestErrorHandler');
// Try for default DB
if (!$db->isConnected()) {
$db =& ConnectionManager::getDataSource('default');
}
// Add test prefix
$config = $db->config;
$config['prefix'] .= 'test_suite_';
// Set up db connection
ConnectionManager::create('test_suite', $config);
// Get db connection
$this->db =& ConnectionManager::getDataSource('test_suite');
$this->db->fullDebug = false;
}
/** /**
* Load fixtures specified in var $fixtures. * Load fixtures specified in var $fixtures.
* *

View file

@ -43,7 +43,13 @@ class CakeTestFixture extends Object {
*/ */
function __construct(&$db) { function __construct(&$db) {
$this->db =& $db; $this->db =& $db;
$this->init();
}
/**
* Initialize the fixture.
*
*/
function init() {
if (isset($this->import) && (is_string($this->import) || is_array($this->import))) { if (isset($this->import) && (is_string($this->import) || is_array($this->import))) {
$import = array(); $import = array();
@ -118,9 +124,11 @@ class CakeTestFixture extends Object {
$this->fields[$this->primaryKey[0]]['key'] = 'primary'; $this->fields[$this->primaryKey[0]]['key'] = 'primary';
} }
foreach($this->fields as $index => $field) { if (isset($this->fields)) {
if (empty($field['default'])) { foreach($this->fields as $index => $field) {
unset($this->fields[$index]['default']); if (empty($field['default'])) {
unset($this->fields[$index]['default']);
}
} }
} }
} }