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 {
var $controller;
var $testCase;
function testCase(&$testCase) {
$this->testCase =& $testCase;
}
function _invoke (&$controller, $params, $missingAction = false) {
$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) {
}
/**
* 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
* when params['requested'] is set.
*
* @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 $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')
* @param array $params Parameters
*
* @return mixed What is returned from action (if $requested is true), or view rendered html
*
* @access protected
*/
function requestAction($url, $return = 'result', $data = null, $method = 'post') {
if (is_array($data) && !empty($data)) {
$data = array('data' => $data);
function requestAction($url, $params = array()) {
$default = array(
'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;
} else {
$_POST = $data;
}
}
$return = $params['return'];
unset($params['data']);
unset($params['method']);
unset($params['return']);
$dispatcher =& new CakeTestDispatcher();
$params = array();
$dispatcher->testCase($this);
if (low($return) != 'result') {
$params['return'] = 0;
@ -129,10 +253,17 @@ class CakeTestCase extends UnitTestCase {
$result = ob_get_clean();
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 = am($result, array('title' => $dispatcher->controller->__viewClass->pageTitle));
$result = array();
foreach($viewVars as $var) {
$result[$var] = $view->getVar($var);
}
if (!empty($view->pageTitle)) {
$result = am($result, array('title' => $view->pageTitle));
}
}
} else {
@ -143,6 +274,18 @@ class CakeTestCase extends UnitTestCase {
$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;
}
/**
@ -161,27 +304,7 @@ class CakeTestCase extends UnitTestCase {
// Set up DB connection
if (isset($this->fixtures) && low($method) == 'start') {
// 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;
$this->_initDb();
$this->_loadFixtures();
}
@ -268,11 +391,37 @@ class CakeTestCase extends UnitTestCase {
*
* @access public
*/
function getTests() {
function getTests() {
$methods = am(am(array('start', 'startCase'), parent::getTests()), array('endCase', 'end'));
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.
*

View file

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