PhptTestCase.php (8810B)
1 <?php 2 /** 3 * PHPUnit 4 * 5 * Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * * Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * * Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * * Neither the name of Sebastian Bergmann nor the names of his 21 * contributors may be used to endorse or promote products derived 22 * from this software without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 27 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 28 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 29 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 30 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 34 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 * POSSIBILITY OF SUCH DAMAGE. 36 * 37 * @package PHPUnit 38 * @subpackage Extensions_PhptTestCase 39 * @author Sebastian Bergmann <sebastian@phpunit.de> 40 * @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de> 41 * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License 42 * @link http://www.phpunit.de/ 43 * @since File available since Release 3.1.4 44 */ 45 46 if (stream_resolve_include_path('PEAR/RunTest.php')) { 47 $currentErrorReporting = error_reporting(E_ERROR | E_WARNING | E_PARSE); 48 require_once 'PEAR/RunTest.php'; 49 error_reporting($currentErrorReporting); 50 } 51 52 /** 53 * Wrapper to run .phpt test cases. 54 * 55 * @package PHPUnit 56 * @subpackage Extensions_PhptTestCase 57 * @author Sebastian Bergmann <sebastian@phpunit.de> 58 * @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de> 59 * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License 60 * @link http://www.phpunit.de/ 61 * @since Class available since Release 3.1.4 62 */ 63 class PHPUnit_Extensions_PhptTestCase implements PHPUnit_Framework_Test, PHPUnit_Framework_SelfDescribing 64 { 65 /** 66 * The filename of the .phpt file. 67 * 68 * @var string 69 */ 70 protected $filename; 71 72 /** 73 * Options for PEAR_RunTest. 74 * 75 * @var array 76 */ 77 protected $options = array(); 78 79 /** 80 * Constructs a test case with the given filename. 81 * 82 * @param string $filename 83 * @param array $options 84 */ 85 public function __construct($filename, array $options = array()) 86 { 87 if (!is_string($filename)) { 88 throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); 89 } 90 91 if (!is_file($filename)) { 92 throw new PHPUnit_Framework_Exception( 93 sprintf( 94 'File "%s" does not exist.', 95 $filename 96 ) 97 ); 98 } 99 100 $this->filename = $filename; 101 $this->options = $options; 102 } 103 104 /** 105 * Counts the number of test cases executed by run(TestResult result). 106 * 107 * @return integer 108 */ 109 public function count() 110 { 111 return 1; 112 } 113 114 /** 115 * Runs a test and collects its result in a TestResult instance. 116 * 117 * @param PHPUnit_Framework_TestResult $result 118 * @param array $options 119 * @return PHPUnit_Framework_TestResult 120 */ 121 public function run(PHPUnit_Framework_TestResult $result = NULL, array $options = array()) 122 { 123 if (!class_exists('PEAR_RunTest', FALSE)) { 124 throw new PHPUnit_Framework_Exception('Class PEAR_RunTest not found.'); 125 } 126 127 if (isset($GLOBALS['_PEAR_destructor_object_list']) && 128 is_array($GLOBALS['_PEAR_destructor_object_list']) && 129 !empty($GLOBALS['_PEAR_destructor_object_list'])) { 130 $pearDestructorObjectListCount = count($GLOBALS['_PEAR_destructor_object_list']); 131 } else { 132 $pearDestructorObjectListCount = 0; 133 } 134 135 if ($result === NULL) { 136 $result = new PHPUnit_Framework_TestResult; 137 } 138 139 $coverage = $result->getCollectCodeCoverageInformation(); 140 $options = array_merge($options, $this->options); 141 142 if (!isset($options['include_path'])) { 143 $options['include_path'] = get_include_path(); 144 } 145 146 if ($coverage) { 147 $options['coverage'] = TRUE; 148 } else { 149 $options['coverage'] = FALSE; 150 } 151 152 $currentErrorReporting = error_reporting(E_ERROR | E_WARNING | E_PARSE); 153 $runner = new PEAR_RunTest(new PHPUnit_Extensions_PhptTestCase_Logger, $options); 154 155 if ($coverage) { 156 $runner->xdebug_loaded = TRUE; 157 } else { 158 $runner->xdebug_loaded = FALSE; 159 } 160 161 $result->startTest($this); 162 163 PHP_Timer::start(); 164 165 $buffer = $runner->run($this->filename, $options); 166 $time = PHP_Timer::stop(); 167 168 error_reporting($currentErrorReporting); 169 170 $base = basename($this->filename); 171 $path = dirname($this->filename); 172 $coverageFile = $path . DIRECTORY_SEPARATOR . str_replace( 173 '.phpt', '.xdebug', $base 174 ); 175 $diffFile = $path . DIRECTORY_SEPARATOR . str_replace( 176 '.phpt', '.diff', $base 177 ); 178 $expFile = $path . DIRECTORY_SEPARATOR . str_replace( 179 '.phpt', '.exp', $base 180 ); 181 $logFile = $path . DIRECTORY_SEPARATOR . str_replace( 182 '.phpt', '.log', $base 183 ); 184 $outFile = $path . DIRECTORY_SEPARATOR . str_replace( 185 '.phpt', '.out', $base 186 ); 187 $phpFile = $path . DIRECTORY_SEPARATOR . str_replace( 188 '.phpt', '.php', $base 189 ); 190 191 if (is_object($buffer) && $buffer instanceof PEAR_Error) { 192 $result->addError( 193 $this, 194 new PHPUnit_Framework_Exception($buffer->getMessage()), 195 $time 196 ); 197 } 198 199 else if ($buffer == 'SKIPPED') { 200 $result->addFailure($this, new PHPUnit_Framework_SkippedTestError, 0); 201 } 202 203 else if ($buffer != 'PASSED') { 204 $expContent = file_get_contents($expFile); 205 $outContent = file_get_contents($outFile); 206 207 $result->addFailure( 208 $this, 209 new PHPUnit_Framework_ComparisonFailure( 210 $expContent, 211 $outContent, 212 $expContent, 213 $outContent 214 ), 215 $time 216 ); 217 } 218 219 foreach (array($diffFile, $expFile, $logFile, $phpFile, $outFile) as $file) { 220 if (file_exists($file)) { 221 unlink($file); 222 } 223 } 224 225 if ($coverage && file_exists($coverageFile)) { 226 eval('$coverageData = ' . file_get_contents($coverageFile) . ';'); 227 unset($coverageData[$phpFile]); 228 229 $result->getCodeCoverage()->append($coverageData, $this); 230 unlink($coverageFile); 231 } 232 233 $result->endTest($this, $time); 234 235 // Do not invoke PEAR's destructor mechanism for PHP 4 236 // as it raises an E_STRICT. 237 if ($pearDestructorObjectListCount == 0) { 238 unset($GLOBALS['_PEAR_destructor_object_list']); 239 } else { 240 $count = count($GLOBALS['_PEAR_destructor_object_list']) - $pearDestructorObjectListCount; 241 242 for ($i = 0; $i < $count; $i++) { 243 array_pop($GLOBALS['_PEAR_destructor_object_list']); 244 } 245 } 246 247 return $result; 248 } 249 250 /** 251 * Returns the name of the test case. 252 * 253 * @return string 254 */ 255 public function getName() 256 { 257 return $this->toString(); 258 } 259 260 /** 261 * Returns a string representation of the test case. 262 * 263 * @return string 264 */ 265 public function toString() 266 { 267 return $this->filename; 268 } 269 }