home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Servidores / xampp-win32-1.6.7-installer.exe / php / PEAR / PHPUnit2 / Framework / TestSuite.php < prev    next >
Encoding:
PHP Script  |  2008-07-02  |  14.9 KB  |  555 lines

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  3.  
  4. /**
  5.  * PHP Version 5
  6.  *
  7.  * Copyright (c) 2002-2006, 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    PHPUnit2
  41.  * @author     Sebastian Bergmann <sb@sebastian-bergmann.de>
  42.  * @copyright  2002-2006 Sebastian Bergmann <sb@sebastian-bergmann.de>
  43.  * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
  44.  * @version    CVS: $Id: TestSuite.php,v 1.26.2.11 2005/12/17 16:04:56 sebastian Exp $
  45.  * @link       http://pear.php.net/package/PHPUnit2
  46.  * @since      File available since Release 2.0.0
  47.  */
  48.  
  49. require_once 'PHPUnit2/Framework/Test.php';
  50. require_once 'PHPUnit2/Framework/TestCase.php';
  51. require_once 'PHPUnit2/Framework/TestResult.php';
  52. require_once 'PHPUnit2/Runner/BaseTestRunner.php';
  53. require_once 'PHPUnit2/Util/Fileloader.php';
  54.  
  55. /**
  56.  * A TestSuite is a composite of Tests. It runs a collection of test cases.
  57.  *
  58.  * Here is an example using the dynamic test definition.
  59.  *
  60.  * <code>
  61.  * <?php
  62.  * $suite = new PHPUnit2_Framework_TestSuite;
  63.  * $suite->addTest(new MathTest('testPass'));
  64.  * ?>
  65.  * </code>
  66.  *
  67.  * Alternatively, a TestSuite can extract the tests to be run automatically.
  68.  * To do so you pass a ReflectionClass instance for your
  69.  * PHPUnit2_Framework_TestCase class to the PHPUnit2_Framework_TestSuite
  70.  * constructor.
  71.  *
  72.  * <code>
  73.  * <?php
  74.  * $suite = new PHPUnit2_Framework_TestSuite(
  75.  *   new ReflectionClass('MathTest')
  76.  * );
  77.  * ?>
  78.  * </code>
  79.  *
  80.  * This constructor creates a suite with all the methods starting with
  81.  * "test" that take no arguments.
  82.  *
  83.  * @category   Testing
  84.  * @package    PHPUnit2
  85.  * @author     Sebastian Bergmann <sb@sebastian-bergmann.de>
  86.  * @copyright  2002-2006 Sebastian Bergmann <sb@sebastian-bergmann.de>
  87.  * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
  88.  * @version    Release: 2.3.6
  89.  * @link       http://pear.php.net/package/PHPUnit2
  90.  * @since      Class available since Release 2.0.0
  91.  */
  92. class PHPUnit2_Framework_TestSuite implements PHPUnit2_Framework_Test {
  93.     /**
  94.      * The name of the test suite.
  95.      *
  96.      * @var    string
  97.      * @access private
  98.      */
  99.     private $name = '';
  100.  
  101.     /**
  102.      * The tests in the test suite.
  103.      *
  104.      * @var    array
  105.      * @access private
  106.      */
  107.     private $tests = array();
  108.  
  109.     /**
  110.      * Constructs a new TestSuite:
  111.      *
  112.      *   - PHPUnit2_Framework_TestSuite() constructs an empty TestSuite.
  113.      *
  114.      *   - PHPUnit2_Framework_TestSuite(ReflectionClass) constructs a
  115.      *     TestSuite from the given class.
  116.      *
  117.      *   - PHPUnit2_Framework_TestSuite(ReflectionClass, String)
  118.      *     constructs a TestSuite from the given class with the given
  119.      *     name.
  120.      *
  121.      *   - PHPUnit2_Framework_TestSuite(String) either constructs a
  122.      *     TestSuite from the given class (if the passed string is the
  123.      *     name of an existing class) or constructs an empty TestSuite
  124.      *     with the given name.
  125.      *
  126.      * @param  mixed  $theClass
  127.      * @param  string $name
  128.      * @throws Exception
  129.      * @access public
  130.      */
  131.     public function __construct($theClass = '', $name = '') {
  132.         $argumentsValid = FALSE;
  133.  
  134.         if (is_object($theClass) &&
  135.             $theClass instanceof ReflectionClass) {
  136.             $argumentsValid = TRUE;
  137.         }
  138.  
  139.         else if (is_string($theClass) && $theClass !== '' && class_exists($theClass)) {
  140.             $argumentsValid = TRUE;
  141.  
  142.             if ($name == '') {
  143.                 $name = $theClass;
  144.             }
  145.  
  146.             $theClass = new ReflectionClass($theClass);
  147.         }
  148.  
  149.         else if (is_string($theClass)) {
  150.             $this->setName($theClass);
  151.             return;
  152.         }
  153.  
  154.         if (!$argumentsValid) {
  155.             throw new Exception;
  156.         }
  157.  
  158.         if ($name != '') {
  159.             $this->setName($name);
  160.         } else {
  161.             $this->setName($theClass->getName());
  162.         }
  163.  
  164.         $constructor = $theClass->getConstructor();
  165.  
  166.         if ($constructor === NULL ||
  167.             !$constructor->isPublic()) {
  168.             $this->addTest(
  169.               self::warning(
  170.                 sprintf(
  171.                   'Class %s has no public constructor',
  172.  
  173.                   $theClass->getName()
  174.                 )
  175.               )
  176.             );
  177.  
  178.             return;
  179.         }
  180.  
  181.         $methods = $theClass->getMethods();
  182.         $names   = array();
  183.  
  184.         foreach ($methods as $method) {
  185.             $this->addTestMethod($method, $names, $theClass);
  186.         }
  187.  
  188.         if (empty($this->tests)) {
  189.             $this->addTest(
  190.               self::warning(
  191.                 sprintf(
  192.                   'No tests found in %s',
  193.  
  194.                   $theClass->getName()
  195.                 )
  196.               )
  197.             );
  198.         }
  199.     }
  200.  
  201.     /**
  202.      * Returns a string representation of the test suite.
  203.      *
  204.      * @return string
  205.      * @access public
  206.      */
  207.     public function toString() {
  208.         return $this->getName();
  209.     }
  210.  
  211.     /**
  212.      * Adds a test to the suite.
  213.      *
  214.      * @param  PHPUnit2_Framework_Test $test
  215.      * @access public
  216.      */
  217.     public function addTest(PHPUnit2_Framework_Test $test) {
  218.         $this->tests[] = $test;
  219.     }
  220.  
  221.     /**
  222.      * Adds the tests from the given class to the suite.
  223.      *
  224.      * @param  mixed $testClass
  225.      * @access public
  226.      */
  227.     public function addTestSuite($testClass) {
  228.         if (is_string($testClass) &&
  229.             class_exists($testClass)) {
  230.             $testClass = new ReflectionClass($testClass);
  231.         }
  232.  
  233.         if (is_object($testClass) &&
  234.             $testClass instanceof ReflectionClass) {
  235.             $this->addTest(new PHPUnit2_Framework_TestSuite($testClass));
  236.         }
  237.     }
  238.  
  239.     /**
  240.      * Wraps both <code>addTest()</code> and <code>addTestSuite</code>
  241.      * as well as the separate import statements for the user's convenience.
  242.      *
  243.      * If the named file cannot be read or there are no new tests that can be
  244.      * added, a <code>PHPUnit2_Framework_Warning</code> will be created instead,
  245.      * leaving the current test run untouched.
  246.      *
  247.      * @param  string $filename
  248.      * @throws Exception
  249.      * @access public
  250.      * @since  Method available since Release 2.3.0
  251.      * @author Stefano F. Rausch <stefano@rausch-e.net>
  252.      */
  253.     public function addTestFile($filename) {
  254.         if (!is_string($filename) || !file_exists($filename)) {
  255.             throw new Exception;
  256.         }
  257.  
  258.         $declaredClasses = get_declared_classes();
  259.  
  260.         PHPUnit2_Util_Fileloader::checkAndLoad($filename);
  261.  
  262.         $newClasses = array_values(
  263.           array_diff(get_declared_classes(), $declaredClasses)
  264.         );
  265.  
  266.         $testsFound = 0;
  267.  
  268.         foreach ($newClasses as $class) {
  269.             if (preg_match('"Tests?$"', $class)) {
  270.                 try {
  271.                     $suiteMethod = new ReflectionMethod(
  272.                       $class, PHPUnit2_Runner_BaseTestRunner::SUITE_METHODNAME
  273.                     );
  274.  
  275.                     $this->addTest($suiteMethod->invoke(NULL));
  276.                 } catch (ReflectionException $e) {
  277.                     $this->addTestSuite(new ReflectionClass($class));
  278.                 }
  279.  
  280.                 $testsFound++;
  281.             }
  282.         }
  283.  
  284.         if ($testsFound == 0) {
  285.             $this->addTest(
  286.               new PHPUnit2_Framework_Warning('No tests found in file ' . $filename)
  287.             );
  288.         }
  289.     }
  290.  
  291.     /**
  292.      * Wrapper for addTestFile() that adds multiple test files.
  293.      *
  294.      * @param  Array $filenames
  295.      * @throws Exception
  296.      * @access public
  297.      * @since  Method available since Release 2.3.0
  298.      */
  299.     public function addTestFiles($filenames) {
  300.         foreach ($filenames as $filename) {
  301.             $this->addTestFile($filename);
  302.         }
  303.     }
  304.  
  305.     /**
  306.      * Counts the number of test cases that will be run by this test.
  307.      *
  308.      * @return integer
  309.      * @access public
  310.      */
  311.     public function countTestCases() {
  312.         $count = 0;
  313.  
  314.         foreach ($this->tests as $test) {
  315.             $count += $test->countTestCases();
  316.         }
  317.  
  318.         return $count;
  319.     }
  320.  
  321.     /**
  322.      * @param  ReflectionClass $theClass
  323.      * @param  string          $name
  324.      * @return PHPUnit2_Framework_Test
  325.      * @access public
  326.      * @static
  327.      */
  328.     public static function createTest(ReflectionClass $theClass, $name) {
  329.         if (!$theClass->isInstantiable()) {
  330.             return self::warning(
  331.               sprintf(
  332.                 'Cannot instantiate test case %s.',
  333.                 $theClass->getName()
  334.               )
  335.             );
  336.         }
  337.  
  338.         $constructor = $theClass->getConstructor();
  339.  
  340.         if ($constructor !== NULL) {
  341.             $parameters = $constructor->getParameters();
  342.  
  343.             if (sizeof($parameters) == 0) {
  344.                 $test = $theClass->newInstance();
  345.  
  346.                 if ($test instanceof PHPUnit2_Framework_TestCase) {
  347.                     $test->setName($name);
  348.                 }
  349.             }
  350.  
  351.             else if (sizeof($parameters) == 1 &&
  352.                      $parameters[0]->getClass() === NULL) {
  353.                 $test = $theClass->newInstance($name);
  354.             }
  355.  
  356.             else {
  357.                 return self::warning(
  358.                   sprintf(
  359.                     'Constructor of class %s is not TestCase($name) or TestCase().',
  360.                     $theClass->getName()
  361.                   )
  362.                 );
  363.             }
  364.         }
  365.  
  366.         return $test;
  367.     }
  368.  
  369.     /**
  370.      * Creates a default TestResult object.
  371.      *
  372.      * @return PHPUnit2_Framework_TestResult
  373.      * @access protected
  374.      */
  375.     protected function createResult() {
  376.         return new PHPUnit2_Framework_TestResult;
  377.     }
  378.  
  379.     /**
  380.      * Returns the name of the suite.
  381.      *
  382.      * @return string
  383.      * @access public
  384.      */
  385.     public function getName() {
  386.         return $this->name;
  387.     }
  388.  
  389.     /**
  390.      * Runs the tests and collects their result in a TestResult.
  391.      *
  392.      * @param  PHPUnit2_Framework_TestResult $result
  393.      * @return PHPUnit2_Framework_TestResult
  394.      * @throws Exception
  395.      * @access public
  396.      */
  397.     public function run($result = NULL) {
  398.         if ($result === NULL) {
  399.             $result = $this->createResult();
  400.         }
  401.  
  402.         // XXX: Workaround for missing ability to declare type-hinted parameters as optional.
  403.         else if (!($result instanceof PHPUnit2_Framework_TestResult)) {
  404.             throw new Exception(
  405.               'Argument 1 must be an instance of PHPUnit2_Framework_TestResult.'
  406.             );
  407.         }
  408.  
  409.         $result->startTestSuite($this);
  410.  
  411.         foreach ($this->tests as $test) {
  412.             if ($result->shouldStop()) {
  413.                 break;
  414.             }
  415.  
  416.             $this->runTest($test, $result);
  417.         }
  418.  
  419.         $result->endTestSuite($this);
  420.  
  421.         return $result;
  422.     }
  423.  
  424.     /**
  425.      * Runs a test.
  426.      *
  427.      * @param  PHPUnit2_Framework_Test        $test
  428.      * @param  PHPUnit2_Framework_TestResult  $testResult
  429.      * @access public
  430.      */
  431.     public function runTest(PHPUnit2_Framework_Test $test, PHPUnit2_Framework_TestResult $result) {
  432.         $test->run($result);
  433.     }
  434.  
  435.     /**
  436.      * Sets the name of the suite.
  437.      *
  438.      * @param  string
  439.      * @access public
  440.      */
  441.     public function setName($name) {
  442.         $this->name = $name;
  443.     }
  444.  
  445.     /**
  446.      * Returns the test at the given index.
  447.      *
  448.      * @param  integer
  449.      * @return PHPUnit2_Framework_Test
  450.      * @access public
  451.      */
  452.     public function testAt($index) {
  453.         if (isset($this->tests[$index])) {
  454.             return $this->tests[$index];
  455.         } else {
  456.             return FALSE;
  457.         }
  458.     }
  459.  
  460.     /**
  461.      * Returns the number of tests in this suite.
  462.      *
  463.      * @return integer
  464.      * @access public
  465.      */
  466.     public function testCount() {
  467.         return sizeof($this->tests);
  468.     }
  469.  
  470.     /**
  471.      * Returns the tests as an enumeration.
  472.      *
  473.      * @return array
  474.      * @access public
  475.      */
  476.     public function tests() {
  477.         return $this->tests;
  478.     }
  479.  
  480.     /**
  481.      * @param  ReflectionMethod $method
  482.      * @param  array            $names
  483.      * @param  ReflectionClass  $theClass
  484.      * @access private
  485.      */
  486.     private function addTestMethod(ReflectionMethod $method, &$names, ReflectionClass $theClass) {
  487.         $name = $method->getName();
  488.  
  489.         if (in_array($name, $names)) {
  490.             return;
  491.         }
  492.  
  493.         if ($this->isPublicTestMethod($method)) {
  494.             $names[] = $name;
  495.  
  496.             $this->addTest(
  497.               self::createTest(
  498.                 $theClass,
  499.                 $name
  500.               )
  501.             );
  502.         }
  503.  
  504.         else if ($this->isTestMethod($method)) {
  505.             $this->addTest(
  506.               self::warning(
  507.                 sprintf(
  508.                   'Test method is not public: %s',
  509.  
  510.                   $name
  511.                 )
  512.               )
  513.             );
  514.         }
  515.     }
  516.  
  517.     /**
  518.      * @param  ReflectionMethod $method
  519.      * @return boolean
  520.      * @access private
  521.      */
  522.     private function isPublicTestMethod(ReflectionMethod $method) {
  523.         return ($this->isTestMethod($method) &&
  524.                 $method->isPublic());
  525.     }
  526.  
  527.     /**
  528.      * @param  ReflectionMethod $method
  529.      * @return boolean
  530.      * @access private
  531.      */
  532.     private function isTestMethod(ReflectionMethod $method) {
  533.         return (substr($method->name, 0, 4) == 'test');
  534.     }
  535.  
  536.     /**
  537.      * @param  string  $message
  538.      * @return PHPUnit2_Framework_Warning
  539.      * @access private
  540.      */
  541.     private static function warning($message) {
  542.         require_once 'PHPUnit2/Framework/Warning.php';
  543.         return new PHPUnit2_Framework_Warning($message);
  544.     }
  545. }
  546.  
  547. /*
  548.  * Local variables:
  549.  * tab-width: 4
  550.  * c-basic-offset: 4
  551.  * c-hanging-comment-ender-p: nil
  552.  * End:
  553.  */
  554. ?>
  555.