diff --git a/cake/console/libs/task_collection.php b/cake/console/libs/task_collection.php new file mode 100644 index 000000000..0c858d574 --- /dev/null +++ b/cake/console/libs/task_collection.php @@ -0,0 +1,93 @@ +_Dispatch = $Dispatcher; + } +/** + * Loads/constructs a task. Will return the instance in the registry if it already exists. + * + * @param string $task Task name to load + * @param array $settings Settings for the task. + * @param boolean $enable Whether or not this task should be enabled by default + * @return Task A task object, Either the existing loaded task or a new one. + * @throws MissingTaskFileException, MissingTaskClassException when the task could not be found + */ + public function load($task, $settings = array(), $enable = true) { + list($plugin, $name) = pluginSplit($task, true); + + if (isset($this->_loaded[$name])) { + return $this->_loaded[$name]; + } + $taskFile = Inflector::underscore($name); + $taskClass = $name . 'Task'; + if (!class_exists($taskClass)) { + $taskFile = $this->_getPath($taskFile); + require_once $taskFile; + if (!class_exists($taskClass)) { + throw new MissingTaskClassException($taskClass); + } + } + + $this->_loaded[$name] = new $taskClass($this->_Dispatch); + if ($enable === true) { + $this->_enabled[] = $name; + } + return $this->_loaded[$name]; + } + +/** + * Find a task file on one of the paths. + * + * @param string $file Underscored name of the file to find missing .php + * @return string Filename to the task + * @throw MissingTaskFileException + */ + protected function _getPath($file) { + foreach ($this->_Dispatch->shellPaths as $path) { + $taskPath = $path . 'tasks' . DS . $file . '.php'; + if (file_exists($taskPath)) { + return $taskPath; + } + } + throw new MissingTaskFileException($file . '.php'); + } + +} +/** + * Exceptions used by the TaskCollection. + */ +class MissingTaskFileException extends RuntimeException { } + +class MissingTaskClassException extends RuntimeException { } \ No newline at end of file diff --git a/cake/tests/cases/console/libs/task_collection.test.php b/cake/tests/cases/console/libs/task_collection.test.php new file mode 100644 index 000000000..a10abb615 --- /dev/null +++ b/cake/tests/cases/console/libs/task_collection.test.php @@ -0,0 +1,168 @@ +getMock('ShellDispatcher', array(), array(), '', false); + $dispatcher->shellPaths = App::path('shells'); + $this->Tasks = new TaskCollection($dispatcher); + } + +/** + * teardown + * + * @return void + */ + function teardown() { + unset($this->Tasks); + } + +/** + * test triggering callbacks on loaded tasks + * + * @return void + */ + function testLoad() { + $result = $this->Tasks->load('DbConfig'); + $this->assertType('DbConfigTask', $result); + $this->assertType('DbConfigTask', $this->Tasks->DbConfig); + + $result = $this->Tasks->attached(); + $this->assertEquals(array('DbConfig'), $result, 'attached() results are wrong.'); + + $this->assertTrue($this->Tasks->enabled('DbConfig')); + } + +/** + * test load and enable = false + * + * @return void + */ + function testLoadWithEnableFalse() { + $result = $this->Tasks->load('DbConfig', array(), false); + $this->assertType('DbConfigTask', $result); + $this->assertType('DbConfigTask', $this->Tasks->DbConfig); + + $this->assertFalse($this->Tasks->enabled('DbConfig'), 'DbConfigTask should be disabled'); + } +/** + * test missinghelper exception + * + * @expectedException MissingTaskFileException + * @return void + */ + function testLoadMissingTaskFile() { + $result = $this->Tasks->load('ThisTaskShouldAlwaysBeMissing'); + } + +/** + * test loading a plugin helper. + * + * @return void + */ + function testLoadPluginTask() { + $this->markTestIncomplete('Not done'); + App::build(array( + 'plugins' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'plugins' . DS), + )); + $result = $this->Tasks->load('TestPlugin.OtherTask'); + $this->assertType('OtherTaskTask', $result, 'Task class is wrong.'); + $this->assertType('OtherTaskTask', $this->Tasks->OtherTask, 'Class is wrong'); + + App::build(); + } + +/** + * test unload() + * + * @return void + */ + function testUnload() { + $this->markTestIncomplete('Not done'); + $this->Tasks->load('Extract'); + $this->Tasks->load('Fixture'); + + $result = $this->Tasks->attached(); + $this->assertEquals(array('Extract', 'Fixture'), $result, 'loaded tasks is wrong'); + + $this->Tasks->unload('Fixture'); + $this->assertFalse(isset($this->Tasks->Fixture)); + $this->assertTrue(isset($this->Tasks->Extract)); + + $result = $this->Tasks->attached(); + $this->assertEquals(array('Extract'), $result, 'loaded tasks is wrong'); + } + +/** + * test triggering callbacks. + * + * @return void + */ + function testTrigger() { + $this->markTestIncomplete('Not done'); + } + +/** + * test trigger and disabled tasks. + * + * @return void + */ + function testTriggerWithDisabledTasks() { + $this->markTestIncomplete('Not done'); + } + +/** + * test normalizeObjectArray + * + * @return void + */ + function testnormalizeObjectArray() { + $tasks = array( + 'Html', + 'Foo.Bar' => array('one', 'two'), + 'Something', + 'Banana.Apple' => array('foo' => 'bar') + ); + $result = TaskCollection::normalizeObjectArray($tasks); + $expected = array( + 'Html' => array('class' => 'Html', 'settings' => array()), + 'Bar' => array('class' => 'Foo.Bar', 'settings' => array('one', 'two')), + 'Something' => array('class' => 'Something', 'settings' => array()), + 'Apple' => array('class' => 'Banana.Apple', 'settings' => array('foo' => 'bar')), + ); + $this->assertEquals($expected, $result); + } +} \ No newline at end of file