Вход Регистрация
Файл: framework/dev/SapphireTestReporter.php
Строк: 420
<?php
if(!class_exists('PHPUnit_Framework_TestResult'false)) require_once 'PHPUnit/Framework/TestResult.php';
if(!
class_exists('PHPUnit_Framework_TestListener'false)) require_once 'PHPUnit/Framework/TestListener.php';

/**#@+
 * @var int
 */
/**
 * Failure test status constant
 */
define('TEST_FAILURE', -1);
/**
 * Error test status constant
 */
define('TEST_ERROR'0);
/**
 * Success test status constant
 */
define('TEST_SUCCESS'1);
/**
 * Incomplete test status constant
 */
define('TEST_INCOMPLETE'2);
/**#@-*/

/**
 * Gathers details about PHPUnit2 test suites as they
 * are been executed. This does not actually format any output
 * but simply gathers extended information about the overall
 * results of all suites & their tests for use elsewhere.
 *
 * Changelog:
 *  0.6 First created [David Spurr]
 *  0.7 Added fix to getTestException provided [Glen Ogilvie]
 *
 * @package framework
 * @subpackage testing
 *
 * @version 0.7 2006-03-12
 * @author David Spurr
 */
class SapphireTestReporter implements PHPUnit_Framework_TestListener {
    
/**
     * Holds array of suites and total number of tests run
     * @var array
     */
    
protected $suiteResults;
    
/**
     * Holds data of current suite that is been run
     * @var array
     */
    
protected $currentSuite;
    
/**
     * Holds data of current test that is been run
     * @var array
     */
    
protected $currentTest;
    
/**
     * Whether PEAR Benchmark_Timer is available for timing
     * @var boolean
     */
    
protected $hasTimer;
    
/**
     * Holds the PEAR Benchmark_Timer object
     * @var obj Benchmark_Timer
     */
    
protected $timer;

    protected 
$startTestTime;

    
/**
     * An array of all the test speeds
     */
    
protected $testSpeeds = array();

    
/**
     * Constructor, checks to see availability of PEAR Benchmark_Timer and
     * sets up basic properties
     *
     * @access public
     * @return void
     */
    
public function __construct() {
        @include_once 
'Benchmark/Timer.php';
        if(
class_exists('Benchmark_Timer')) {
            
$this->timer = new Benchmark_Timer();
            
$this->hasTimer true;
        } else {
            
$this->hasTimer false;
        }

        
$this->suiteResults = array(
            
'suites'      => array(),         // array of suites run
            
'hasTimer'    => $this->hasTimer// availability of PEAR Benchmark_Timer
            
'totalTests'  => 0                // total number of tests run
        
);
    }

    
/**
     * Returns the suite results
     *
     * @access public
     * @return array Suite results
     */
    
public function getSuiteResults() {
        return 
$this->suiteResults;
    }

    
/**
     * Sets up the container for result details of the current test suite when
     * each suite is first run
     *
     * @access public
     * @param obj PHPUnit2_Framework_TestSuite, the suite that is been run
     * @return void
     */
    
public function startTestSuitePHPUnit_Framework_TestSuite $suite) {
        if(
strlen($suite->getName())) {
            
$this->endCurrentTestSuite();
        
$this->currentSuite = array(
            
'suite'      => $suite,  // the test suite
            
'tests'      => array(), // the tests in the suite
            
'errors'     => 0,       // number of tests with errors (including setup errors)
            
'failures'   => 0,       // number of tests which failed
            
'incomplete' => 0,       // number of tests that were not completed correctly
                
'error'         => null);     // Any error encountered during setup of the test suite
    
}
    }

    
/**
     * Sets up the container for result details of the current test when each
     * test is first run
     *
     * @access public
     * @param obj PHPUnit_Framework_Test, the test that is being run
     * @return void
     */
    
public function startTest(PHPUnit_Framework_Test $test) {
        
$this->startTestTime microtime(true);

        if(
$test instanceof PHPUnit_Framework_TestCase) {
            
$this->endCurrentTest();
            
$this->currentTest = array(
                
// the name of the test (without the suite name)
                
'name'        => preg_replace('((.*))'''$test->toString()),
                
// execution time of the test
                
'timeElapsed' => 0,
                
// status of the test execution
                
'status'      => TEST_SUCCESS,
                
// user message of test result
                
'message'     => '',
                
// original caught exception thrown by test upon failure/error
                
'exception'   => NULL,
                
// Stacktrace used for exception handling
                
'trace'          => NULL,
                
// a unique ID for this test (used for identification purposes in results)
                
'uid'         => md5(microtime())
            );
            if(
$this->hasTimer$this->timer->start();
        }
    }

    
/**
     * Logs the specified status to the current test, or if no test is currently
     * run, to the test suite.
     * @param integer $status Status code
     * @param string $message Message to log
     * @param string $exception Exception body related to this message
     * @param array $trace Stacktrace
     */
    
protected function addStatus($status$message$exception$trace) {
        
// Build status body to be saved
        
$status = array(
            
'status' => $status,
            
'message' => $message,
            
'exception' => $exception,
            
'trace' => $trace
        
);

        
// Log either to current test or suite record
        
if($this->currentTest) {
            
$this->currentTest array_merge($this->currentTest$status);
        } else {
            
$this->currentSuite['error'] = $status;
        }
    }

    
/**
     * Adds the failure detail to the current test and increases the failure
     * count for the current suite
     *
     * @access public
     * @param obj PHPUnit_Framework_Test, current test that is being run
     * @param obj PHPUnit_Framework_AssertationFailedError, PHPUnit error
     * @return void
     */
    
public function addFailure(PHPUnit_Framework_Test $testPHPUnit_Framework_AssertionFailedError $e$time) {
        
$this->currentSuite['failures']++;
        
$this->addStatus(TEST_FAILURE$e->toString(), $this->getTestException($test$e), $e->getTrace());
    }

    
/**
     * Adds the error detail to the current test and increases the error
     * count for the current suite
     *
     * @access public
     * @param obj PHPUnit_Framework_Test, current test that is being run
     * @param obj PHPUnit_Framework_AssertationFailedError, PHPUnit error
     * @return void
     */
    
public function addError(PHPUnit_Framework_Test $testException $e$time) {
        
$this->currentSuite['errors']++;
        
$this->addStatus(TEST_ERROR$e->getMessage(), $this->getTestException($test$e), $e->getTrace());
    }

    
/**
     * Adds the test incomplete detail to the current test and increases the incomplete
     * count for the current suite
     *
     * @access public
     * @param obj PHPUnit_Framework_Test, current test that is being run
     * @param obj PHPUnit_Framework_AssertationFailedError, PHPUnit error
     * @return void
     */
    
public function addIncompleteTest(PHPUnit_Framework_Test $testException $e$time) {
        
$this->currentSuite['incomplete']++;
        
$this->addStatus(TEST_INCOMPLETE$e->toString(), $this->getTestException($test$e), $e->getTrace());
    }

    
/**
     * Not used
     *
     * @param PHPUnit_Framework_Test $test
     * @param unknown_type $time
     */
    
public function addSkippedTest(PHPUnit_Framework_Test $testException $e$time) {
        
// not implemented
    
}


    
/**
     * Cleanly end the current test
     */
    
protected function endCurrentTest() {
        if(!
$this->currentTest) return;

        
// Time the current test
        
$testDuration microtime(true) - $this->startTestTime;
        
$this->testSpeeds[$this->currentSuite['suite']->getName() . '.' $this->currentTest['name']] = $testDuration;
        if(
$this->hasTimer) {
            
$this->timer->stop();
            
$this->currentTest['timeElapsed'] = $this->timer->timeElapsed();
        }

        
// Save and reset current state
        
array_push($this->currentSuite['tests'], $this->currentTest);
        
$this->currentTest null;
    }

    
/**
     * Upon completion of a test, records the execution time (if available) and adds the test to
     * the tests performed in the current suite.
     *
     * @access public
     * @param obj PHPUnit_Framework_Test, current test that is being run
     * @return void
     */
    
public function endTestPHPUnit_Framework_Test $test$time) {
        
$this->endCurrentTest();
        if(
method_exists($test'getActualOutput')) {
            
$output $test->getActualOutput();
            if(
$output) echo "nOutput:n$output";
        }
    }

    
/**
     * Cleanly end the current test suite
     */
    
protected function endCurrentTestSuite() {
        if(!
$this->currentSuite) return;

        
// Ensure any current test is ended along with the current suite
        
$this->endCurrentTest();

        
// Save and reset current state
        
array_push($this->suiteResults['suites'], $this->currentSuite);
        
$this->currentSuite null;
    }

    
/**
     * Upon completion of a test suite adds the suite to the suties performed
     *
     * @access public
     * @param obj PHPUnit_Framework_TestSuite, current suite that is being run
     * @return void
     */
    
public function endTestSuitePHPUnit_Framework_TestSuite $suite) {
        if(
strlen($suite->getName())) {
            
$this->endCurrentTestSuite();
        }
    }

    
/**
     * Risky test.
     *
     * @param PHPUnit_Framework_Test $test
     * @param Exception              $e
     * @param float                  $time
     * @since  Method available since Release 3.8.0
     */
    
public function addRiskyTest(PHPUnit_Framework_Test $testException $e$time) {
        
// Stub out to support PHPUnit 3.8
    
}

    
/**
     * Trys to get the original exception thrown by the test on failure/error
     * to enable us to give a bit more detail about the failure/error
     *
     * @access private
     * @param obj PHPUnit_Framework_Test, current test that is being run
     * @param obj PHPUnit_Framework_AssertationFailedError, PHPUnit error
     * @return array
     */
    
private function getTestException(PHPUnit_Framework_Test $testException $e) {
        
// get the name of the testFile from the test
        
$testName preg_replace('/(.*)((.*[^)]))/''\2'$test->toString());
        
$trace $e->getTrace();
        
// loop through the exception trace to find the original exception
        
for($i 0$i count($trace); $i++) {

            if(
array_key_exists('file'$trace[$i])) {
                if(
stristr($trace[$i]['file'], $testName.'.php') != false) return $trace[$i];
            }
            if(
array_key_exists('file:protected'$trace[$i])) {
                if(
stristr($trace[$i]['file:protected'], $testName.'.php') != false) return $trace[$i];
            }
        }
    }

    
/**
     * Writes a status message to the output stream in a user readable HTML format
     * @param string $name Name of the object that generated the error
     * @param string $message Message of the error
     * @param array $trace Stacktrace
     */
    
protected function writeResultError($name$message$trace) {
        echo 
"<div class="failure"><h2 class="test-case">&otimes; "$this->testNameToPhrase($name) ."</h2>";
        echo 
"<pre>".htmlentities($messageENT_COMPAT'UTF-8')."</pre>";
        echo 
SS_Backtrace::get_rendered_backtrace($trace);
        echo 
"</div>";
    }

    
/**
     * Display error bar if it exists
     */
    
public function writeResults() {
        
$passCount 0;
        
$failCount 0;
        
$testCount 0;
        
$incompleteCount 0;
        
$errorCount 0// Includes both suite and test level errors

        // Ensure that the current suite is cleanly ended.
        // A suite may not end correctly if there was an error during setUp
        
$this->endCurrentTestSuite();

        foreach(
$this->suiteResults['suites'] as $suite) {

            
// Report suite error. In the case of fatal non-success messages
            // These should be reported as errors. Failure/Success relate only
            // to individual tests directly
            
if($suite['error']) {
                
$errorCount++;
                
$this->writeResultError(
                    
$suite['suite']->getName(),
                    
$suite['error']['message'],
                    
$suite['error']['trace']
                );
            }

            
// Run through all tests in this suite
            
foreach($suite['tests'] as $test) {
                
$testCount++;
                switch(
$test['status']) {
                    case 
TEST_ERROR$errorCount++; break;
                    case 
TEST_INCOMPLETE$incompleteCount++; break;
                    case 
TEST_SUCCESS$passCount++; break;
                    case 
TEST_FAILURE$failCount++; break;
                }

                
// Report test error
                
if ($test['status'] != TEST_SUCCESS) {
                    
$this->writeResultError(
                        
$test['name'],
                        
$test['message'],
                        
$test['trace']
                    );
                }
            }
        }
        
$result = ($failCount || $errorCount) ? 'fail' 'pass';
        echo 
"<div class="status $result">";
        echo 
"<h2><span>$testCount</span> tests run: <span>$passCount</span> passes, <span>$failCount</span> failures,"
            
" and <span>$incompleteCount</span> incomplete with <span>$errorCount</span> errors</h2>";
        echo 
"</div>";

    }

    protected function 
testNameToPhrase($name) {
        return 
ucfirst(preg_replace("/([a-z])([A-Z])/""$1 $2"$name));
    }
}
Онлайн: 0
Реклама