home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2008 February / PCWFEB08.iso / Software / Resources / Developers / XAMPP 1.5.4 / Windows installer / xampp-win32-1.5.4-installer.exe / xampp / php / pear / PHPUnit / Skeleton.php < prev    next >
Encoding:
PHP Script  |  2005-12-02  |  14.1 KB  |  449 lines

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  3.  
  4. /**
  5.  * PHP Version 4
  6.  *
  7.  * Copyright (c) 2002-2005, Sebastian Bergmann <sb@sebastian-bergmann.de>.
  8.  * All rights reserved.
  9.  *
  10.  * Redistribution and use in source and binary forms, with or without
  11.  * modification, are permitted provided that the following conditions
  12.  * are met:
  13.  *
  14.  *   * Redistributions of source code must retain the above copyright
  15.  *     notice, this list of conditions and the following disclaimer.
  16.  * 
  17.  *   * Redistributions in binary form must reproduce the above copyright
  18.  *     notice, this list of conditions and the following disclaimer in
  19.  *     the documentation and/or other materials provided with the
  20.  *     distribution.
  21.  *
  22.  *   * Neither the name of Sebastian Bergmann nor the names of his
  23.  *     contributors may be used to endorse or promote products derived
  24.  *     from this software without specific prior written permission.
  25.  *
  26.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  27.  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  28.  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  29.  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  30.  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  31.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  32.  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  33.  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  34.  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRIC
  35.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  36.  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  37.  * POSSIBILITY OF SUCH DAMAGE.
  38.  *
  39.  * @category   Testing
  40.  * @package    PHPUnit
  41.  * @author     Scott Mattocks <scott@crisscott.com>
  42.  * @copyright  2002-2005 Sebastian Bergmann <sb@sebastian-bergmann.de>
  43.  * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
  44.  * @version    CVS: $Id: Skeleton.php,v 1.8 2005/11/10 09:47:14 sebastian Exp $
  45.  * @link       http://pear.php.net/package/PHPUnit
  46.  * @since      File available since Release 1.1.0
  47.  */
  48.  
  49. /**
  50.  * Class for creating a PHPUnit_TestCase skeleton file.
  51.  *
  52.  * This class will take a classname as a parameter on construction and will
  53.  * create a PHP file that contains the skeleton of a PHPUnit_TestCase
  54.  * subclass. The test case will contain a test foreach method of the class.
  55.  * Methods of the parent class will, by default, be excluded from the test
  56.  * class. Passing and optional construction parameter will include them.
  57.  *
  58.  * Example
  59.  *
  60.  *   <?php
  61.  *   require_once 'PHPUnit/Skeleton.php';
  62.  *   $ps = new PHPUnit_Skeleton('PHPUnit_Skeleton', 'PHPUnit/Skeleton.php');
  63.  *
  64.  *   // Generate the test class.
  65.  *   // Default settings will not include any parent class methods, but
  66.  *   // will include private methods.
  67.  *   $ps->createTestClass();
  68.  *
  69.  *   // Write the new test class to file.
  70.  *   // By default, code to run the test will be included.
  71.  *   $ps->writeTestClass();
  72.  *   ?>
  73.  *
  74.  * Now open the skeleton class and fill in the details.
  75.  * If you run the test as is, all tests will fail and
  76.  * you will see plenty of undefined constant errors.
  77.  *
  78.  * @category   Testing
  79.  * @package    PHPUnit
  80.  * @author     Scott Mattocks <scott@crisscott.com>
  81.  * @copyright  2002-2005 Sebastian Bergmann <sb@sebastian-bergmann.de>
  82.  * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
  83.  * @version    Release: 1.3.2
  84.  * @link       http://pear.php.net/package/PHPUnit
  85.  * @since      Class available since Release 1.1.0
  86.  */
  87. class PHPUnit_Skeleton {
  88.     /**
  89.      * Path to the class file to create a skeleton for.
  90.      * @var string
  91.      */
  92.     var $classPath;
  93.  
  94.     /**
  95.      * The name of the class
  96.      * @var string
  97.      */
  98.     var $className;
  99.  
  100.     /**
  101.      * Path to the configuration file needed by class to test.
  102.      * @var string
  103.      */
  104.     var $configFile;
  105.  
  106.     /**
  107.      * Whether or not to include the methods of the parent class when testing.
  108.      * @var boolean
  109.      */
  110.     var $includeParents;
  111.  
  112.     /**
  113.      * Whether or not to test private methods.
  114.      * @var boolean
  115.      */
  116.     var $includePrivate;
  117.  
  118.     /**
  119.      * The test class that will be created.
  120.      * @var string
  121.      */
  122.     var $testClass;
  123.  
  124.     /**
  125.      * Constructor. Sets the class members and check that the class
  126.      * to test is accessible.
  127.      *
  128.      * @access public
  129.      * @param  string  $className
  130.      * @param  string  $classPath
  131.      * @param  boolean $includeParents Wheter to include the parent's methods in the test.
  132.      * @return void
  133.      */
  134.     function PHPUnit_Skeleton($className, $classPath, $includeParents = FALSE, $includePrivate = TRUE) {
  135.         // Set up the members.
  136.         if (@is_readable($classPath)) {
  137.             $this->className = $className;
  138.             $this->classPath = $classPath;
  139.         } else {
  140.             $this->_handleErrors($classPath . ' is not readable. Cannot create test class.');
  141.         }
  142.  
  143.         // Do we want to include parent methods?
  144.         $this->includeParents = $includeParents;
  145.  
  146.         // Do we want to allow private methods?
  147.         $this->includePrivate = $includePrivate;
  148.     }
  149.  
  150.     /**
  151.      * The class to test may require a special config file before it can be
  152.      * instantiated. This method lets you set that file.
  153.      *
  154.      * @access public
  155.      * @param  string $configPath
  156.      * @return void
  157.      */
  158.     function setConfigFile($configFile) {
  159.         // Check that the file is readable
  160.         if (@is_readable($configFile)) {
  161.             $this->configFile = $configFile;
  162.         } else {
  163.             $this->_handleErrors($configFile . ' is not readable. Cannot create test class.');
  164.         }
  165.     }
  166.  
  167.     /**
  168.      * Create the code that will be the skeleton of the test case.
  169.      *
  170.      * The test case must have a clss definition, one var, a constructor
  171.      * setUp, tearDown, and methods. Optionally and by default the code
  172.      * to run the test is added when the class is written to file.
  173.      *
  174.      * @access public
  175.      * @param  none
  176.      * @return void
  177.      */
  178.     function createTestClass() {
  179.         // Instantiate the object.
  180.         if (isset($this->configFile)) {
  181.             require_once $this->configFile;
  182.         }
  183.  
  184.         require_once $this->classPath;
  185.  
  186.         // Get the methods.
  187.         $classMethods = get_class_methods($this->className);
  188.  
  189.         // Remove the parent methods if needed.
  190.         if (!$this->includeParents) {
  191.             $parentMethods = get_class_methods(get_parent_class($this->className));
  192.  
  193.             if (count($parentMethods)) {
  194.                 $classMethods = array_diff($classMethods, $parentMethods);
  195.             }
  196.         }
  197.  
  198.         // Create the class definition, constructor, setUp and tearDown.
  199.         $this->_createDefinition();
  200.         $this->_createConstructor();
  201.         $this->_createSetUpTearDown();
  202.  
  203.         if (count($classMethods)) {
  204.             // Foreach method create a test case.
  205.             foreach ($classMethods as $method) {
  206.                 // Unless it is the constructor.
  207.                 if (strcasecmp($this->className, $method) !== 0) {
  208.                   // Check for private methods.
  209.                   if (!$this->includePrivate && strpos($method, '_') === 0) {
  210.                       continue;
  211.                   } else {
  212.                       $this->_createMethod($method);
  213.                   }
  214.                 }
  215.             }
  216.         }
  217.  
  218.         // Finis off the class.
  219.         $this->_finishClass();
  220.     }
  221.  
  222.     /**
  223.      * Create the class definition.
  224.      *
  225.      * The definition consist of a header comment, require statment
  226.      * for getting the PHPUnit file, the actual class definition,
  227.      * and the definition of the class member variable.
  228.      *
  229.      * All of the code needed for the new class is stored in the
  230.      * testClass member.
  231.      *
  232.      * @access private
  233.      * @param  none
  234.      * @return void
  235.      */
  236.     function _createDefinition() {
  237.         // Create header comment.
  238.         $this->testClass =
  239.           "/**\n" .
  240.           " * PHPUnit test case for " . $this->className . "\n" .
  241.           " * \n" .
  242.           " * The method skeletons below need to be filled in with \n" .
  243.           " * real data so that the tests will run correctly. Replace \n" .
  244.           " * all EXPECTED_VAL and PARAM strings with real data. \n" .
  245.           " * \n" .
  246.           " * Created with PHPUnit_Skeleton on " . date('Y-m-d') . "\n" .
  247.           " */\n";
  248.  
  249.         // Add the require statements.
  250.         $this->testClass .= "require_once 'PHPUnit.php';\n";
  251.  
  252.         // Add the class definition and variable definition.
  253.         $this->testClass .=
  254.           "class " . $this->className . "Test extends PHPUnit_TestCase {\n\n" .
  255.           "    var \$" . $this->className . ";\n\n";
  256.     }
  257.  
  258.     /**
  259.      * Create the class constructor. (PHP4 style)
  260.      *
  261.      * The constructor simply calls the PHPUnit_TestCase method.
  262.      * This code is taken from the PHPUnit documentation.
  263.      *
  264.      * All of the code needed for the new class is stored in the
  265.      * testClass member.
  266.      *
  267.      * @access private
  268.      * @param  none
  269.      * @return void
  270.      */
  271.     function _createConstructor() {
  272.         // Create the test class constructor.
  273.         $this->testClass.=
  274.           "    function " . $this->className . "Test(\$name)\n" .
  275.           "    {\n" .
  276.           "        \$this->PHPUnit_TestCase(\$name);\n" .
  277.           "    }\n\n";
  278.     }
  279.  
  280.     /**
  281.      * Create setUp and tearDown methods.
  282.      *
  283.      * The setUp method creates the instance of the object to test.
  284.      * The tearDown method releases the instance.
  285.      * This code is taken from the PHPUnit documentation.
  286.      *
  287.      * All of the code needed for the new class is stored in the
  288.      * testClass member.
  289.      *
  290.      * @access private
  291.      * @param  none
  292.      * @return void
  293.      */
  294.     function _createSetUpTearDown() {
  295.         // Create the setUp method.
  296.         $this->testClass .=
  297.           "    function setUp()\n" .
  298.           "    {\n";
  299.  
  300.         if (isset($this->configFile)) {
  301.             $this->testClass .=
  302.             "        require_once '" . $this->configFile . "';\n";
  303.         }
  304.  
  305.         $this->testClass .=
  306.           "        require_once '" . $this->classPath . "';\n" .
  307.           "        \$this->" . $this->className . " =& new " . $this->className . "(PARAM);\n" .
  308.           "    }\n\n";
  309.  
  310.         // Create the tearDown method.
  311.         $this->testClass .=
  312.           "    function tearDown()\n" .
  313.           "    {\n" .
  314.           "        unset(\$this->" . $this->className . ");\n" .
  315.           "    }\n\n";
  316.     }
  317.  
  318.     /**
  319.      * Create a basic skeleton for test methods.
  320.      *
  321.      * This code is taken from the PHPUnit documentation.
  322.      *
  323.      * All of the code needed for the new class is stored in the
  324.      * testClass member.
  325.      *
  326.      * @access private
  327.      * @param  none
  328.      * @return void
  329.      */
  330.     function _createMethod($methodName) {
  331.         // Create a test method.
  332.         $this->testClass .=
  333.           "    function test" . $methodName . "()\n" .
  334.           "    {\n" .
  335.           "        \$result   = \$this->" . $this->className . "->" . $methodName . "(PARAM);\n" .
  336.           "        \$expected = EXPECTED_VAL;\n" .
  337.           "        \$this->assertEquals(\$expected, \$result);\n" .
  338.           "    }\n\n";
  339.     }
  340.  
  341.     /**
  342.      * Add the closing brace needed for a proper class definition.
  343.      *
  344.      * All of the code needed for the new class is stored in the
  345.      * testClass member.
  346.      *
  347.      * @access private
  348.      * @param  none
  349.      * @return void
  350.      */
  351.     function _finishClass() {
  352.         // Close off the class.
  353.         $this->testClass.= "}\n";
  354.     }
  355.  
  356.     /**
  357.      * Create the code that will actually run the test.
  358.      *
  359.      * This code is added by default so that the test can be run
  360.      * just by running the file. To have it not added pass false
  361.      * as the second parameter to the writeTestClass method.
  362.      * This code is taken from the PHPUnit documentation.
  363.      *
  364.      * All of the code needed for the new class is stored in the
  365.      * testClass member.
  366.      *
  367.      * @access private
  368.      * @param  none
  369.      * @return void
  370.      */
  371.     function _createTest() {
  372.         // Create a call to the test.
  373.         $test =
  374.           "// Running the test.\n" .
  375.           "\$suite  = new PHPUnit_TestSuite('" . $this->className . "Test');\n" .
  376.           "\$result = PHPUnit::run(\$suite);\n" .
  377.           "echo \$result->toString();\n";
  378.  
  379.         return $test;
  380.     }
  381.  
  382.     /**
  383.      * Write the test class to file.
  384.      *
  385.      * This will write the test class created using the createTestClass
  386.      * method to a file called <className>Test.php. By default the file
  387.      * is written to the current directory and will have code to run
  388.      * the test appended to the bottom of the file.
  389.      *
  390.      * @access public
  391.      * @param  string  $destination The directory to write the file to.
  392.      * @param  boolean $addTest     Wheter to add the test running code.
  393.      * @return void
  394.      */
  395.     function writeTestClass($destination = './', $addTest = TRUE) {
  396.         // Check for something to write to file.
  397.         if (!isset($this->testClass)) {
  398.             $this->_handleErrors('Noting to write.', PHPUS_WARNING);
  399.             return;
  400.         }
  401.  
  402.         // Open the destination file.
  403.         $fp = fopen($destination . $this->className . 'Test.php', 'w');
  404.         fwrite($fp, "<?php\n");
  405.  
  406.         // Write the test class.
  407.         fwrite($fp, $this->testClass);
  408.  
  409.         // Add the call to test the class in the file if we were asked to.
  410.         if ($addTest) {
  411.             fwrite($fp, $this->_createTest());
  412.         }
  413.  
  414.         // Close the file.
  415.         fwrite($fp, "?>\n");
  416.         fclose($fp);
  417.     }
  418.  
  419.     /**
  420.      * Error handler.
  421.      *
  422.      * This method should be rewritten to use the prefered error
  423.      * handling method. (PEAR_ErrorStack)
  424.      *
  425.      * @access private
  426.      * @param  string  $message The error message.
  427.      * @param  integer $type    An indication of the severity of the error.
  428.      * @return void             Code may cause PHP to exit.
  429.      */
  430.     function _handleErrors($message, $type = E_USER_ERROR) {
  431.         // For now just echo the message.
  432.         echo $message;
  433.  
  434.         // Check to see if we should quit.
  435.         if ($type == E_USER_ERROR) {
  436.             exit;
  437.         }
  438.     }
  439. }
  440.  
  441. /*
  442.  * Local variables:
  443.  * tab-width: 4
  444.  * c-basic-offset: 4
  445.  * c-hanging-comment-ender-p: nil
  446.  * End:
  447.  */
  448. ?>
  449.