Skip to content

Commit

Permalink
Get the first controller test generation working.
Browse files Browse the repository at this point in the history
  • Loading branch information
markstory committed Mar 31, 2014
1 parent b3ab244 commit a4ee7b0
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 56 deletions.
65 changes: 26 additions & 39 deletions src/Console/Command/Task/TestTask.php
Expand Up @@ -15,10 +15,12 @@
namespace Cake\Console\Command\Task;

use Cake\Console\Shell;
use Cake\Controller\Controller;
use Cake\Core\App;
use Cake\Core\Configure;
use Cake\Core\Plugin;
use Cake\Error;
use Cake\ORM\Association;
use Cake\ORM\TableRegistry;
use Cake\Utility\Folder;
use Cake\Utility\Inflector;
Expand Down Expand Up @@ -202,9 +204,9 @@ public function bake($type, $className) {
if (!empty($this->params['fixtures'])) {
$fixtures = array_map('trim', explode(',', $this->params['fixtures']));
$this->_fixtures = $fixtures;
} elseif ($this->typeCanDetectFixtures($type) && $this->isLoadableClass($realType, $fullClassName)) {
} elseif ($this->typeCanDetectFixtures($type) && class_exists($fullClassName)) {
$this->out(__d('cake_console', 'Bake is detecting possible fixtures...'));
$testSubject = $this->buildTestSubject($type, $className);
$testSubject = $this->buildTestSubject($type, $fullClassName);
$this->generateFixtureList($testSubject);
}

Expand Down Expand Up @@ -281,34 +283,26 @@ public function getClassName($objectType) {
*/
public function typeCanDetectFixtures($type) {
$type = strtolower($type);
return in_array($type, ['controller', 'model']);
}

/**
* Check if a class with the given package is loaded or can be loaded.
*
* @param string $package The package of object you are generating tests for eg. controller
* @param string $class the Classname of the class the test is being generated for.
* @return boolean
*/
public function isLoadableClass($package, $class) {
$classname = App::classname($class, $package);
return !empty($classname);
return in_array($type, ['controller', 'table']);
}

/**
* Construct an instance of the class to be tested.
* So that fixtures can be detected
*
* @param string $type The Type of object you are generating tests for eg. controller
* @param string $class the Classname of the class the test is being generated for.
* @param string $type The type of object you are generating tests for eg. controller
* @param string $class The classname of the class the test is being generated for.
* @return object And instance of the class that is going to be tested.
*/
public function buildTestSubject($type, $class) {
TableRegistry::clear();
$class = $this->getRealClassName($type, $class);
if (strtolower($type) === 'model') {
$instance = TableRegistry::get($class);
if (strtolower($type) === 'table') {
list($namespace, $name) = namespaceSplit($class);
$name = str_replace('Table', '', $name);
if ($this->plugin) {
$name = $this->plugin . '.' . $name;
}
$instance = TableRegistry::get($name);
} else {
$instance = new $class();
}
Expand Down Expand Up @@ -411,21 +405,17 @@ public function generateFixtureList($subject) {
* @return void
*/
protected function _processModel($subject) {
$this->_addFixture($subject->name);
$associated = $subject->getAssociated();
foreach ($associated as $alias => $type) {
$className = $subject->{$alias}->name;
if (!isset($this->_fixtures[$className])) {
$this->_processModel($subject->{$alias});
$this->_addFixture($subject->alias());
foreach ($subject->associations()->keys() as $alias) {
$assoc = $subject->association($alias);
$name = $assoc->target()->alias();
if (!isset($this->_fixtures[$name])) {
$this->_processModel($assoc->target());
}
if ($type === 'hasAndBelongsToMany') {
if (!empty($subject->hasAndBelongsToMany[$alias]['with'])) {
list(, $joinModel) = pluginSplit($subject->hasAndBelongsToMany[$alias]['with']);
} else {
$joinModel = Inflector::classify($subject->hasAndBelongsToMany[$alias]['joinTable']);
}
if (!isset($this->_fixtures[$joinModel])) {
$this->_processModel($subject->{$joinModel});
if ($assoc->type() === Association::MANY_TO_MANY) {
$junction = $assoc->junction();
if (!isset($this->_fixtures[$junction->alias()])) {
$this->_processModel($junction);
}
}
}
Expand All @@ -440,10 +430,7 @@ protected function _processModel($subject) {
*/
protected function _processController($subject) {
$subject->constructClasses();
$models = [Inflector::classify($subject->name)];
if (!empty($subject->uses)) {
$models = $subject->uses;
}
$models = [$subject->modelClass];
foreach ($models as $model) {
list(, $model) = pluginSplit($model);
$this->_processModel($subject->{$model});
Expand All @@ -463,7 +450,7 @@ protected function _addFixture($name) {
} else {
$prefix = 'app.';
}
$fixture = $prefix . Inflector::underscore($name);
$fixture = $prefix . Inflector::underscore(Inflector::singularize($name));
$this->_fixtures[$name] = $fixture;
}

Expand Down
35 changes: 18 additions & 17 deletions tests/TestCase/Console/Command/Task/TestTaskTest.php
Expand Up @@ -374,27 +374,25 @@ public function testBakeModelTest() {
* @return void
*/
public function testBakeControllerTest() {
$this->markTestIncomplete('This test explodes because of namespicing');
Configure::write('App.namespace', 'TestApp');

$this->Task->expects($this->once())->method('createFile')->will($this->returnValue(true));
$this->Task->expects($this->once())->method('isLoadableClass')->will($this->returnValue(true));
$this->Task->expects($this->once())
->method('createFile')
->will($this->returnValue(true));

$result = $this->Task->bake('Controller', 'TestTaskComments');
$result = $this->Task->bake('Controller', 'PostsController');

$this->assertContains("App::uses('TestTaskCommentsController', 'Controller')", $result);
$this->assertContains('class TestTaskCommentsControllerTest extends ControllerTestCase', $result);
$this->assertContains("use TestApp\Controller\PostsController", $result);
$this->assertContains('class PostsControllerTest extends ControllerTestCase', $result);

$this->assertNotContains('function setUp()', $result);
$this->assertNotContains("\$this->TestTaskComments = new TestTaskCommentsController()", $result);
$this->assertNotContains("\$this->TestTaskComments->constructClasses()", $result);
$this->assertNotContains("\$this->Posts = new PostsController()", $result);
$this->assertNotContains("\$this->Posts->constructClasses()", $result);

$this->assertNotContains('function tearDown()', $result);
$this->assertNotContains('unset($this->TestTaskComments)', $result);
$this->assertNotContains('unset($this->Posts)', $result);

$this->assertContains("'app.test_task_article'", $result);
$this->assertContains("'app.test_task_comment'", $result);
$this->assertContains("'app.test_task_tag'", $result);
$this->assertContains("'app.articles_tag'", $result);
$this->assertContains("'app.post'", $result);
}

/**
Expand All @@ -403,9 +401,11 @@ public function testBakeControllerTest() {
* @return void
*/
public function testBakeComponentTest() {
$this->markTestIncomplete('Model tests need reworking.');
Configure::write('App.namespace', 'TestApp');
$this->Task->expects($this->once())->method('createFile')->will($this->returnValue(true));

$this->Task->expects($this->once())
->method('createFile')
->will($this->returnValue(true));

$result = $this->Task->bake('Component', 'Apple');

Expand All @@ -430,8 +430,9 @@ public function testBakeComponentTest() {
* @return void
*/
public function testBakeBehaviorTest() {
$this->markTestIncomplete('Model tests need reworking.');
$this->Task->expects($this->once())->method('createFile')->will($this->returnValue(true));
$this->Task->expects($this->once())
->method('createFile')
->will($this->returnValue(true));

$result = $this->Task->bake('Behavior', 'Example');

Expand Down

0 comments on commit a4ee7b0

Please sign in to comment.