Parcourir la source

ZF-11053
- Various fixes to make the test assets more usable: phpunit.xml is filled, single bootstrap
- Additions to test generated assets: controller tests w/ view action tests
- Fix in the zf.php to use getenv instead of $_ENV


git-svn-id: http://framework.zend.com/svn/framework/standard/trunk@23766 44c647ce-9c0f-0410-b52a-842ac1e357ba

ralph il y a 15 ans
Parent
commit
154cbbeb9d

+ 3 - 2
bin/zf.php

@@ -306,8 +306,9 @@ class ZF
         ini_set('display_errors', true);
         
         // support the changing of the current working directory, necessary for some providers
-        if (isset($_ENV['ZEND_TOOL_CURRENT_WORKING_DIRECTORY'])) {
-            chdir($_ENV['ZEND_TOOL_CURRENT_WORKING_DIRECTORY']);
+        $cwd = getenv('ZEND_TOOL_CURRENT_WORKING_DIRECTORY');
+        if ($cwd != '' && realpath($cwd)) {
+            chdir($cwd);
         }
         
         if (!$this->_configFile) {

+ 14 - 9
library/Zend/Db/Table/Row/Abstract.php

@@ -540,15 +540,7 @@ abstract class Zend_Db_Table_Row_Abstract implements ArrayAccess, IteratorAggreg
          * Do this only if primary key value(s) were changed.
          */
         if (count($pkDiffData) > 0) {
-            $depTables = $this->_getTable()->getDependentTables();
-            if (!empty($depTables)) {
-                $pkNew = $this->_getPrimaryKey(true);
-                $pkOld = $this->_getPrimaryKey(false);
-                foreach ($depTables as $tableClass) {
-                    $t = $this->_getTableFromString($tableClass);
-                    $t->_cascadeUpdate($this->getTableClass(), $pkOld, $pkNew);
-                }
-            }
+            $this->_doUpdateCascade(); // broken out for overriding
         }
 
         /**
@@ -586,6 +578,19 @@ abstract class Zend_Db_Table_Row_Abstract implements ArrayAccess, IteratorAggreg
 
         return $primaryKey;
     }
+    
+    protected function _doUpdateCascade()
+    {
+        $depTables = $this->_getTable()->getDependentTables();
+        if (!empty($depTables)) {
+            $pkNew = $this->_getPrimaryKey(true);
+            $pkOld = $this->_getPrimaryKey(false);
+            foreach ($depTables as $tableClass) {
+                $t = $this->_getTableFromString($tableClass);
+                $t->_cascadeUpdate($this->getTableClass(), $pkOld, $pkNew);
+            }
+        }
+    }
 
     /**
      * Deletes existing rows.

+ 38 - 3
library/Zend/Test/PHPUnit/ControllerTestCase.php

@@ -19,12 +19,15 @@
  * @version    $Id$
  */
 
-/** @see PHPUnit_Framework_TestCase */
-require_once 'PHPUnit/Framework/TestCase.php';
-
 /** @see PHPUnit_Runner_Version */
 require_once 'PHPUnit/Runner/Version.php';
 
+/**
+ * Depending on version, include the proper PHPUnit support
+ * @see PHPUnit_Autoload
+ */
+require_once (version_compare(PHPUnit_Runner_Version::id(), '3.5.0', '>=')) ? 'PHPUnit/Autoload.php' : 'PHPUnit/Framework.php';
+
 /** @see Zend_Controller_Front */
 require_once 'Zend/Controller/Front.php';
 
@@ -1155,6 +1158,38 @@ abstract class Zend_Test_PHPUnit_ControllerTestCase extends PHPUnit_Framework_Te
         }
         return $this->_query;
     }
+    
+    /**
+     * URL Helper
+     * 
+     * @param array $urlOptions
+     * @param string $name
+     * @param bool $reset
+     * @param bool $encode
+     */
+    public function url($urlOptions = array(), $name = null, $reset = false, $encode = true)
+    {
+        $frontController = $this->getFrontController();
+        $router = $frontController->getRouter();
+        if (!$router instanceof Zend_Controller_Router_Rewrite) {
+            throw new Exception('This url helper utility function only works when the router is of type Zend_Controller_Router_Rewrite');
+        }
+        if (count($router->getRoutes()) == 0) {
+            $router->addDefaultRoutes();
+        }
+        return $router->assemble($urlOptions, $name, $reset, $encode);
+    }
+    
+    public function urlizeOptions($urlOptions, $actionControllerModuleOnly = true)
+    {
+        $ccToDash = new Zend_Filter_Word_CamelCaseToDash();
+        foreach ($urlOptions as $n => $v) {
+            if (in_array($n, array('action', 'controller', 'module'))) {
+                $urlOptions[$n] = $ccToDash->filter($v);
+            }
+        }
+        return $urlOptions;
+    }
 
     /**
      * Increment assertion count

+ 228 - 0
library/Zend/Tool/Project/Context/Zf/TestApplicationActionMethod.php

@@ -0,0 +1,228 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    Zend_Tool
+ * @subpackage Framework
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id: ActionMethod.php 20096 2010-01-06 02:05:09Z bkarwin $
+ */
+
+/**
+ * @see Zend_Tool_Project_Context_Interface
+ */
+require_once 'Zend/Tool/Project/Context/Interface.php';
+
+/**
+ * @see Zend_Reflection_File
+ */
+require_once 'Zend/Reflection/File.php';
+
+/**
+ * This class is the front most class for utilizing Zend_Tool_Project
+ *
+ * A profile is a hierarchical set of resources that keep track of
+ * items within a specific project.
+ *
+ * @category   Zend
+ * @package    Zend_Tool
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Tool_Project_Context_Zf_TestApplicationActionMethod implements Zend_Tool_Project_Context_Interface
+{
+
+    /**
+     * @var Zend_Tool_Project_Profile_Resource
+     */
+    protected $_resource = null;
+
+    /**
+     * @var Zend_Tool_Project_Profile_Resource
+     */
+    protected $_testApplicationControllerResource = null;
+
+    /**
+     * @var string
+     */
+    protected $_testApplicationControllerPath = '';
+
+    /**
+     * @var string
+     */
+    protected $_forActionName = null;
+
+    /**
+     * init()
+     *
+     * @return Zend_Tool_Project_Context_Zf_ActionMethod
+     */
+    public function init()
+    {
+        $this->_forActionName = $this->_resource->getAttribute('forActionName');
+
+        $this->_resource->setAppendable(false);
+        $this->_testApplicationControllerResource = $this->_resource->getParentResource();
+        if (!$this->_testApplicationControllerResource->getContext() instanceof Zend_Tool_Project_Context_Zf_TestApplicationControllerFile) {
+            require_once 'Zend/Tool/Project/Context/Exception.php';
+            throw new Zend_Tool_Project_Context_Exception('ActionMethod must be a sub resource of a TestApplicationControllerFile');
+        }
+        // make the ControllerFile node appendable so we can tack on the actionMethod.
+        $this->_resource->getParentResource()->setAppendable(true);
+
+        $this->_testApplicationControllerPath = $this->_testApplicationControllerResource->getContext()->getPath();
+
+        return $this;
+    }
+
+    /**
+     * getPersistentAttributes
+     *
+     * @return array
+     */
+    public function getPersistentAttributes()
+    {
+        return array(
+            'forActionName' => $this->getForActionName()
+            );
+    }
+
+    /**
+     * getName()
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return 'TestApplicationActionMethod';
+    }
+
+    /**
+     * setResource()
+     *
+     * @param Zend_Tool_Project_Profile_Resource $resource
+     * @return Zend_Tool_Project_Context_Zf_ActionMethod
+     */
+    public function setResource(Zend_Tool_Project_Profile_Resource $resource)
+    {
+        $this->_resource = $resource;
+        return $this;
+    }
+
+    /**
+     * getActionName()
+     *
+     * @return string
+     */
+    public function getForActionName()
+    {
+        return $this->_forActionName;
+    }
+
+    /**
+     * create()
+     *
+     * @return Zend_Tool_Project_Context_Zf_ActionMethod
+     */
+    public function create()
+    {
+        $file = $this->_testApplicationControllerPath;
+        
+        if (!file_exists($file)) {
+            require_once 'Zend/Tool/Project/Context/Exception.php';
+            throw new Zend_Tool_Project_Context_Exception(
+                'Could not create action within test controller ' . $file
+                . ' with action name ' . $this->_forActionName
+                );
+        }
+        
+        $actionParam = $this->getForActionName();
+        $controllerParam = $this->_resource->getParentResource()->getForControllerName();
+        //$moduleParam = null;//
+        
+        /* @var $controllerDirectoryResource Zend_Tool_Project_Profile_Resource */
+        $controllerDirectoryResource = $this->_resource->getParentResource()->getParentResource();
+        if ($controllerDirectoryResource->getParentResource()->getName() == 'TestApplicationModuleDirectory') {
+            $moduleParam = $controllerDirectoryResource->getParentResource()->getForModuleName();
+        } else {
+            $moduleParam = 'default';
+        }
+        
+        
+
+        if ($actionParam == 'index' && $controllerParam == 'Index' && $moduleParam == 'default') {
+            $assert = '$this->assertQueryContentContains("div#welcome h3", "This is your project\'s main page");';
+        } else {
+            $assert = <<<EOS
+\$this->assertQueryContentContains(
+    'div#view-content p',
+    'View script for controller <b>' . \$params['controller'] . '</b> and script/action name <b>' . \$params['action'] . '</b>'
+    );
+EOS;
+        }
+        
+        $codeGenFile = Zend_CodeGenerator_Php_File::fromReflectedFileName($file, true, true);
+        $codeGenFile->getClass()->setMethod(array(
+            'name' => 'test' . ucfirst($actionParam) . 'Action',
+            'body' => <<<EOS
+\$params = array('action' => '$actionParam', 'controller' => '$controllerParam', 'module' => '$moduleParam');
+\$url = \$this->url(\$this->urlizeOptions(\$params));
+\$this->dispatch(\$url);
+
+// assertions
+\$this->assertModule(\$params['module']);
+\$this->assertController(\$params['controller']);
+\$this->assertAction(\$params['action']);
+$assert
+
+EOS
+            ));
+
+        file_put_contents($file, $codeGenFile->generate());
+        
+        return $this;
+    }
+
+    /**
+     * delete()
+     *
+     * @return Zend_Tool_Project_Context_Zf_ActionMethod
+     */
+    public function delete()
+    {
+        // @todo do this
+        return $this;
+    }
+
+    /**
+     * hasActionMethod()
+     *
+     * @param string $controllerPath
+     * @param string $actionName
+     * @return bool
+     */
+    /*
+    public static function hasActionMethod($controllerPath, $actionName)
+    {
+        if (!file_exists($controllerPath)) {
+            return false;
+        }
+
+        $controllerCodeGenFile = Zend_CodeGenerator_Php_File::fromReflectedFileName($controllerPath, true, true);
+        return $controllerCodeGenFile->getClass()->hasMethod('test' . $actionName . 'Action');
+    }
+    */
+
+}

+ 34 - 10
library/Zend/Tool/Project/Context/Zf/TestApplicationControllerFile.php

@@ -68,6 +68,27 @@ class Zend_Tool_Project_Context_Zf_TestApplicationControllerFile extends Zend_To
     }
 
     /**
+     * getPersistentAttributes()
+     *
+     * @return unknown
+     */
+    public function getPersistentAttributes()
+    {
+        $attributes = array();
+
+        if ($this->_forControllerName) {
+            $attributes['forControllerName'] = $this->getForControllerName();
+        }
+
+        return $attributes;
+    }
+    
+    public function getForControllerName()
+    {
+        return $this->_forControllerName;
+    }
+    
+    /**
      * getContents()
      *
      * @return string
@@ -78,23 +99,26 @@ class Zend_Tool_Project_Context_Zf_TestApplicationControllerFile extends Zend_To
         $filter = new Zend_Filter_Word_DashToCamelCase();
 
         $className = $filter->filter($this->_forControllerName) . 'ControllerTest';
-
+        
+        /* @var $controllerDirectoryResource Zend_Tool_Project_Profile_Resource */
+        $controllerDirectoryResource = $this->_resource->getParentResource();
+        if ($controllerDirectoryResource->getParentResource()->getName() == 'TestApplicationModuleDirectory') {
+            $className = ucfirst($controllerDirectoryResource->getParentResource()->getForModuleName())
+                . '_' . $className;
+        }        
+        
         $codeGenFile = new Zend_CodeGenerator_Php_File(array(
-            'requiredFiles' => array(
-                'PHPUnit/Framework/TestCase.php'
-                ),
             'classes' => array(
                 new Zend_CodeGenerator_Php_Class(array(
                     'name' => $className,
-                    'extendedClass' => 'PHPUnit_Framework_TestCase',
+                    'extendedClass' => 'Zend_Test_PHPUnit_ControllerTestCase',
                     'methods' => array(
                         new Zend_CodeGenerator_Php_Method(array(
                             'name' => 'setUp',
-                            'body' => '        /* Setup Routine */'
-                            )),
-                        new Zend_CodeGenerator_Php_Method(array(
-                            'name' => 'tearDown',
-                            'body' => '        /* Tear Down Routine */'
+                            'body' => <<<EOS
+\$this->bootstrap = new Zend_Application(APPLICATION_ENV, APPLICATION_PATH . '/configs/application.ini');
+parent::setUp();
+EOS
                             ))
                         )
                     ))

+ 98 - 0
library/Zend/Tool/Project/Context/Zf/TestApplicationModuleDirectory.php

@@ -0,0 +1,98 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    Zend_Tool
+ * @subpackage Framework
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id: TestApplicationControllerDirectory.php 20096 2010-01-06 02:05:09Z bkarwin $
+ */
+
+/**
+ * @see Zend_Tool_Project_Context_Filesystem_Directory
+ */
+require_once 'Zend/Tool/Project/Context/Filesystem/Directory.php';
+
+/**
+ * This class is the front most class for utilizing Zend_Tool_Project
+ *
+ * A profile is a hierarchical set of resources that keep track of
+ * items within a specific project.
+ *
+ * @category   Zend
+ * @package    Zend_Tool
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Tool_Project_Context_Zf_TestApplicationModuleDirectory extends Zend_Tool_Project_Context_Filesystem_Directory
+{
+
+
+    /**
+     * @var string
+     */
+    protected $_forModuleName = null;
+
+    /**
+     * @var string
+     */
+    protected $_filesystemName = 'moduleDirectory';
+
+    /**
+     * init()
+     *
+     * @return Zend_Tool_Project_Context_Zf_ControllerFile
+     */
+    public function init()
+    {
+        $this->_filesystemName = $this->_forModuleName = $this->_resource->getAttribute('forModuleName');
+        parent::init();
+        return $this;
+    }
+
+    /**
+     * getName()
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return 'TestApplicationModuleDirectory';
+    }
+
+    /**
+     * getPersistentAttributes
+     *
+     * @return array
+     */
+    public function getPersistentAttributes()
+    {
+        return array(
+            'forModuleName' => $this->getForModuleName()
+            );
+    }
+
+    /**
+     * getModuleName()
+     *
+     * @return string
+     */
+    public function getForModuleName()
+    {
+        return $this->_forModuleName;
+    }
+    
+
+}

+ 57 - 0
library/Zend/Tool/Project/Context/Zf/TestApplicationModulesDirectory.php

@@ -0,0 +1,57 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    Zend_Tool
+ * @subpackage Framework
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id: TestApplicationControllerDirectory.php 20096 2010-01-06 02:05:09Z bkarwin $
+ */
+
+/**
+ * @see Zend_Tool_Project_Context_Filesystem_Directory
+ */
+require_once 'Zend/Tool/Project/Context/Filesystem/Directory.php';
+
+/**
+ * This class is the front most class for utilizing Zend_Tool_Project
+ *
+ * A profile is a hierarchical set of resources that keep track of
+ * items within a specific project.
+ *
+ * @category   Zend
+ * @package    Zend_Tool
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Tool_Project_Context_Zf_TestApplicationModulesDirectory extends Zend_Tool_Project_Context_Filesystem_Directory
+{
+
+    /**
+     * @var string
+     */
+    protected $_filesystemName = 'modules';
+
+    /**
+     * getName()
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return 'TestApplicationModulesDirectory';
+    }
+
+}

+ 88 - 0
library/Zend/Tool/Project/Context/Zf/TestPHPUnitBootstrapFile.php

@@ -0,0 +1,88 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    Zend_Tool
+ * @subpackage Framework
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id: TestApplicationBootstrapFile.php 20096 2010-01-06 02:05:09Z bkarwin $
+ */
+
+/**
+ * @see Zend_Tool_Project_Context_Filesystem_File
+ */
+require_once 'Zend/Tool/Project/Context/Filesystem/File.php';
+
+/**
+ * This class is the front most class for utilizing Zend_Tool_Project
+ *
+ * A profile is a hierarchical set of resources that keep track of
+ * items within a specific project.
+ *
+ * @category   Zend
+ * @package    Zend_Tool
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Tool_Project_Context_Zf_TestPHPUnitBootstrapFile extends Zend_Tool_Project_Context_Filesystem_File
+{
+
+    /**
+     * @var string
+     */
+    protected $_filesystemName = 'bootstrap.php';
+
+    /**
+     * getName()
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return 'TestPHPUnitBootstrapFile';
+    }
+    
+    /**
+     * getContents()
+     *
+     * @return string
+     */
+    public function getContents()
+    {
+        $codeGenerator = new Zend_CodeGenerator_Php_File(array(
+            'body' => <<<EOS
+// Define path to application directory
+defined('APPLICATION_PATH')
+    || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));
+
+// Define application environment
+defined('APPLICATION_ENV')
+    || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'testing'));
+
+// Ensure library/ is on include_path
+set_include_path(implode(PATH_SEPARATOR, array(
+    realpath(APPLICATION_PATH . '/../library'),
+    get_include_path(),
+)));
+
+require_once 'Zend/Loader/Autoloader.php';
+Zend_Loader_Autoloader::getInstance();
+
+EOS
+            ));
+        return $codeGenerator->generate();
+    }
+
+}

+ 24 - 0
library/Zend/Tool/Project/Context/Zf/TestPHPUnitConfigFile.php

@@ -53,5 +53,29 @@ class Zend_Tool_Project_Context_Zf_TestPHPUnitConfigFile extends Zend_Tool_Proje
     {
         return 'TestPHPUnitConfigFile';
     }
+    
+    public function getContents()
+    {
+        return <<<EOS
+<phpunit bootstrap="./bootstrap.php">
+    <testsuite name="Application Test Suite">
+        <directory>./application</directory>
+    </testsuite>
+    <testsuite name="Library Test Suite">
+        <directory>./library</directory>
+    </testsuite>
+    
+    <filter>
+        <!-- If Zend Framework is inside your project's library, uncomment this filter -->
+        <!-- 
+        <whitelist>
+            <directory suffix=".php">../../library/Zend</directory>
+        </whitelist>
+        -->
+    </filter>
+</phpunit>
+
+EOS;
+    }
 
 }

+ 21 - 3
library/Zend/Tool/Project/Context/Zf/ViewScriptFile.php

@@ -130,6 +130,18 @@ class Zend_Tool_Project_Context_Zf_ViewScriptFile extends Zend_Tool_Project_Cont
     {
         $contents = '';
 
+        $controllerName = $this->_resource->getParentResource()->getAttribute('forControllerName');
+        
+        $viewsDirectoryResource = $this->_resource
+            ->getParentResource() // view script
+            ->getParentResource() // view controller dir
+            ->getParentResource(); // views dir
+        if ($viewsDirectoryResource->getParentResource()->getName() == 'ModuleDirectory') {
+            $moduleName = $viewsDirectoryResource->getParentResource()->getModuleName();
+        } else {
+            $moduleName = 'default';
+        }
+        
         if ($this->_filesystemName == 'error.phtml') {  // should also check that the above directory is forController=error
             $contents .= <<<EOS
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
@@ -162,7 +174,7 @@ class Zend_Tool_Project_Context_Zf_ViewScriptFile extends Zend_Tool_Project_Cont
 </html>
 
 EOS;
-        } elseif ($this->_forActionName == 'index' && $this->_resource->getParentResource()->getAttribute('forControllerName') == 'Index') {
+        } elseif ($this->_forActionName == 'index' && $controllerName == 'Index' && $moduleName == 'default') {
 
             $contents =<<<EOS
 <style>
@@ -211,8 +223,14 @@ EOS;
 EOS;
 
         } else {
-            $contents = '<br /><br /><center>View script for controller <b>' . $this->_resource->getParentResource()->getAttribute('forControllerName') . '</b>'
-                . ' and script/action name <b>' . $this->_forActionName . '</b></center>';
+            $controllerName = $this->_resource->getParentResource()->getAttribute('forControllerName');
+            $actionName = $this->_forActionName;
+            $contents = <<<EOS
+<br /><br />
+<div id="view-content">
+	<p>View script for controller <b>$controllerName</b> and script/action name <b>$actionName</b></p>
+</div>
+EOS;
         }
         return $contents;
     }

+ 23 - 4
library/Zend/Tool/Project/Provider/Action.php

@@ -131,6 +131,10 @@ class Zend_Tool_Project_Provider_Action
 
         $this->_loadProfile();
 
+        // determine if testing is enabled in the project
+        require_once 'Zend/Tool/Project/Provider/Test.php';
+        $testingEnabled = Zend_Tool_Project_Provider_Test::isTestingEnabled($this->_loadedProfile);
+        
         // Check that there is not a dash or underscore, return if doesnt match regex
         if (preg_match('#[_-]#', $name)) {
             throw new Zend_Tool_Project_Provider_Exception('Action names should be camel cased.');
@@ -149,8 +153,12 @@ class Zend_Tool_Project_Provider_Action
             throw new Zend_Tool_Project_Provider_Exception('This controller (' . $controllerName . ') already has an action named (' . $name . ')');
         }
 
-        $actionMethod = self::createResource($this->_loadedProfile, $name, $controllerName, $module);
+        $actionMethodResource = self::createResource($this->_loadedProfile, $name, $controllerName, $module);
 
+        if ($testingEnabled) {
+            $testActionMethodResource = Zend_Tool_Project_Provider_Test::createApplicationResource($this->_loadedProfile, $controllerName, $name, $module);
+        }
+        
         // get request/response object
         $request = $this->_registry->getRequest();
         $response = $this->_registry->getResponse();
@@ -181,14 +189,25 @@ class Zend_Tool_Project_Provider_Action
         if ($request->isPretend()) {
             $response->appendContent(
                 'Would create an action named ' . $name .
-                ' inside controller at ' . $actionMethod->getParentResource()->getContext()->getPath()
+                ' inside controller at ' . $actionMethodResource->getParentResource()->getContext()->getPath()
                 );
+                
+            if ($testActionMethodResource) {
+                $response->appendContent('Would create an action test in ' . $testActionMethodResource->getParentResource()->getContext()->getPath());
+            }
+                
         } else {
             $response->appendContent(
                 'Creating an action named ' . $name .
-                ' inside controller at ' . $actionMethod->getParentResource()->getContext()->getPath()
+                ' inside controller at ' . $actionMethodResource->getParentResource()->getContext()->getPath()
                 );
-            $actionMethod->create();
+            $actionMethodResource->create();
+            
+            if ($testActionMethodResource) {
+                $response->appendContent('Creating an action test in ' . $testActionMethodResource->getParentResource()->getContext()->getPath());
+                $testActionMethodResource->create();
+            }
+            
             $this->_storeProfile();
         }
 

+ 7 - 6
library/Zend/Tool/Project/Provider/Controller.php

@@ -139,7 +139,7 @@ class Zend_Tool_Project_Provider_Controller
                 $indexActionViewResource = Zend_Tool_Project_Provider_View::createResource($this->_loadedProfile, 'index', $name, $module);
             }
             if ($testingEnabled) {
-                $testControllerResource = Zend_Tool_Project_Provider_Test::createApplicationResource($this->_loadedProfile, $name, 'index', $module);
+                $testActionResource = Zend_Tool_Project_Provider_Test::createApplicationResource($this->_loadedProfile, $name, 'index', $module);
             }
 
         } catch (Exception $e) {
@@ -169,8 +169,8 @@ class Zend_Tool_Project_Provider_Controller
                 $response->appendContent('Would create a view script for the index action method at ' . $indexActionViewResource->getContext()->getPath());
             }
 
-            if ($testControllerResource) {
-                $response->appendContent('Would create a controller test file at ' . $testControllerResource->getContext()->getPath());
+            if ($testActionResource) {
+                $response->appendContent('Would create a controller test file at ' . $testActionResource->getParentResource()->getContext()->getPath());
             }
 
         } else {
@@ -185,9 +185,10 @@ class Zend_Tool_Project_Provider_Controller
                 $indexActionViewResource->create();
             }
 
-            if ($testControllerResource) {
-                $response->appendContent('Creating a controller test file at ' . $testControllerResource->getContext()->getPath());
-                $testControllerResource->create();
+            if ($testActionResource) {
+                $response->appendContent('Creating a controller test file at ' . $testActionResource->getParentResource()->getContext()->getPath());
+                $testActionResource->getParentResource()->create();
+                $testActionResource->create();
             }
 
             $this->_storeProfile();

+ 4 - 0
library/Zend/Tool/Project/Provider/Module.php

@@ -136,6 +136,10 @@ class Zend_Tool_Project_Provider_Module
     {
         $this->_loadProfile(self::NO_PROFILE_THROW_EXCEPTION);
 
+        // determine if testing is enabled in the project
+        require_once 'Zend/Tool/Project/Provider/Test.php';
+        //$testingEnabled = Zend_Tool_Project_Provider_Test::isTestingEnabled($this->_loadedProfile);
+        
         $resources = self::createResources($this->_loadedProfile, $name);
 
         $response = $this->_registry->getResponse();

+ 21 - 6
library/Zend/Tool/Project/Provider/Project.php

@@ -98,6 +98,11 @@ class Zend_Tool_Project_Provider_Project
             'This command created a web project, '
             . 'for more information setting up your VHOST, please see docs/README');
 
+        if (!Zend_Tool_Project_Provider_Test::isPHPUnitAvailable()) {
+            $response->appendContent('Testing Note: ', array('separator' => false, 'color' => 'yellow'));
+            $response->appendContent('PHPUnit was not found in your include_path, therefore no testing actions will be created.');
+        }
+            
         foreach ($newProfile->getIterator() as $resource) {
             $resource->create();
         }
@@ -120,9 +125,16 @@ class Zend_Tool_Project_Provider_Project
 
     protected function _getDefaultProfile()
     {
+        $testAction = '';
+        if (Zend_Tool_Project_Provider_Test::isPHPUnitAvailable()) {
+            $testAction = '                    	<testApplicationActionMethod forActionName="index" />';
+        }
+        
+        $version = Zend_Version::VERSION;
+
         $data = <<<EOS
 <?xml version="1.0" encoding="UTF-8"?>
-<projectProfile type="default" version="1.10">
+<projectProfile type="default" version="$version">
     <projectDirectory>
         <projectProfileFile />
         <applicationDirectory>
@@ -179,12 +191,15 @@ class Zend_Tool_Project_Provider_Project
         <temporaryDirectory enabled="false" />
         <testsDirectory>
             <testPHPUnitConfigFile />
+            <testPHPUnitBootstrapFile />
             <testApplicationDirectory>
-                <testApplicationBootstrapFile />
-            </testApplicationDirectory>
-            <testLibraryDirectory>
-                <testLibraryBootstrapFile />
-            </testLibraryDirectory>
+                <testApplicationControllerDirectory>
+                    <testApplicationControllerFile filesystemName="IndexControllerTest.php" forControllerName="Index">
+$testAction
+                    </testApplicationControllerFile>
+                </testApplicationControllerDirectory>
+      	    </testApplicationDirectory>
+            <testLibraryDirectory />
         </testsDirectory>
     </projectDirectory>
 </projectProfile>

+ 35 - 11
library/Zend/Tool/Project/Provider/Test.php

@@ -55,6 +55,21 @@ class Zend_Tool_Project_Provider_Test extends Zend_Tool_Project_Provider_Abstrac
         return $testsDirectory->isEnabled();
     }
 
+    public static function isPHPUnitAvailable()
+    {
+        if (class_exists('PHPUnit_Runner_Version', false)) {
+            return true;
+        }
+        
+        $included = @include 'PHPUnit/Runner/Version.php';
+        
+        if ($included === false) {
+            return false;
+        } else {
+            return true;
+        }
+    }
+    
     /**
      * createApplicationResource()
      *
@@ -76,22 +91,32 @@ class Zend_Tool_Project_Provider_Test extends Zend_Tool_Project_Provider_Abstrac
 
         $testsDirectoryResource = $profile->search('testsDirectory');
 
-        if (($testAppDirectoryResource = $testsDirectoryResource->search('testApplicationDirectory')) === false) {
-            $testAppDirectoryResource = $testsDirectoryResource->createResource('testApplicationDirectory');
+        // parentOfController could either be application/ or a particular module folder, which is why we use this name
+        if (($testParentOfControllerDirectoryResource = $testsDirectoryResource->search('testApplicationDirectory')) === false) {
+            $testParentOfControllerDirectoryResource = $testsDirectoryResource->createResource('testApplicationDirectory');
         }
 
         if ($moduleName) {
-            //@todo $moduleName
-            $moduleName = '';
+            if (($testAppModulesDirectoryResource = $testParentOfControllerDirectoryResource->search('testApplicationModulesDirectory')) === false) {
+                $testAppModulesDirectoryResource = $testParentOfControllerDirectoryResource->createResource('testApplicationModulesDirectory');
+            }
+            
+            if (($testAppModuleDirectoryResource = $testAppModulesDirectoryResource->search(array('testApplicationModuleDirectory' => array('forModuleName' => $moduleName)))) === false) {
+                $testAppModuleDirectoryResource = $testAppModulesDirectoryResource->createResource('testApplicationModuleDirectory', array('forModuleName' => $moduleName));
+            }
+            
+            $testParentOfControllerDirectoryResource = $testAppModuleDirectoryResource;
         }
 
-        if (($testAppControllerDirectoryResource = $testAppDirectoryResource->search('testApplicationControllerDirectory')) === false) {
-            $testAppControllerDirectoryResource = $testAppDirectoryResource->createResource('testApplicationControllerDirectory');
+        if (($testAppControllerDirectoryResource = $testParentOfControllerDirectoryResource->search('testApplicationControllerDirectory', 'testApplicationModuleDirectory')) === false) {
+            $testAppControllerDirectoryResource = $testParentOfControllerDirectoryResource->createResource('testApplicationControllerDirectory');
         }
 
-        $testAppControllerFileResource = $testAppControllerDirectoryResource->createResource('testApplicationControllerFile', array('forControllerName' => $controllerName));
-
-        return $testAppControllerFileResource;
+        if (($testAppControllerFileResource = $testAppControllerDirectoryResource->search(array('testApplicationControllerFile' => array('forControllerName' => $controllerName)))) === false) {
+            $testAppControllerFileResource = $testAppControllerDirectoryResource->createResource('testApplicationControllerFile', array('forControllerName' => $controllerName));
+        }
+        
+        return $testAppControllerFileResource->createResource('testApplicationActionMethod', array('forActionName' => $actionName));
     }
 
     /**
@@ -120,7 +145,6 @@ class Zend_Tool_Project_Provider_Test extends Zend_Tool_Project_Provider_Abstrac
                     $currentDirectoryResource = $libraryDirectoryResource;
                 }
 
-
             } else {
 
                 if (($libraryFileResource = $currentDirectoryResource->search(array('TestLibraryFile' => array('forClassName' => $libraryClassName)))) === false) {
@@ -147,7 +171,7 @@ class Zend_Tool_Project_Provider_Test extends Zend_Tool_Project_Provider_Abstrac
     /**
      * create()
      *
-     * @param unknown_type $libraryClassName
+     * @param string $libraryClassName
      */
     public function create($libraryClassName)
     {