| [ Index ] |
|
Code source de PRADO 3.0.6 |
1 <?php 2 /** 3 * Base include file for SimpleTest 4 * @package SimpleTest 5 * @subpackage UnitTester 6 * @version $Id: test_case.php 1526 2006-11-28 23:34:00Z wei $ 7 */ 8 9 /**#@+ 10 * Includes SimpleTest files and defined the root constant 11 * for dependent libraries. 12 */ 13 require_once(dirname(__FILE__) . '/invoker.php'); 14 require_once(dirname(__FILE__) . '/errors.php'); 15 require_once(dirname(__FILE__) . '/compatibility.php'); 16 require_once(dirname(__FILE__) . '/scorer.php'); 17 require_once(dirname(__FILE__) . '/expectation.php'); 18 require_once(dirname(__FILE__) . '/dumper.php'); 19 require_once(dirname(__FILE__) . '/simpletest.php'); 20 if (version_compare(phpversion(), '5') >= 0) { 21 require_once(dirname(__FILE__) . '/exceptions.php'); 22 require_once(dirname(__FILE__) . '/reflection_php5.php'); 23 } else { 24 require_once(dirname(__FILE__) . '/reflection_php4.php'); 25 } 26 if (! defined('SIMPLE_TEST')) { 27 /** 28 * @ignore 29 */ 30 define('SIMPLE_TEST', dirname(__FILE__) . '/'); 31 } 32 /**#@-*/ 33 34 /** 35 * Basic test case. This is the smallest unit of a test 36 * suite. It searches for 37 * all methods that start with the the string "test" and 38 * runs them. Working test cases extend this class. 39 * @package SimpleTest 40 * @subpackage UnitTester 41 */ 42 class SimpleTestCase { 43 protected $_label = false; 44 protected $_reporter; 45 protected $_observers; 46 47 /** 48 * Sets up the test with no display. 49 * @param string $label If no test name is given then 50 * the class name is used. 51 * @access public 52 */ 53 function SimpleTestCase($label = false) { 54 if ($label) { 55 $this->_label = $label; 56 } 57 } 58 59 /** 60 * Accessor for the test name for subclasses. 61 * @return string Name of the test. 62 * @access public 63 */ 64 function getLabel() { 65 return $this->_label ? $this->_label : get_class($this); 66 } 67 68 /** 69 * Used to invoke the single tests. 70 * @return SimpleInvoker Individual test runner. 71 * @access public 72 */ 73 function createInvoker() { 74 $invoker = new SimpleErrorTrappingInvoker(new SimpleInvoker($this)); 75 if (version_compare(phpversion(), '5') >= 0) { 76 $invoker = new SimpleExceptionTrappingInvoker($invoker); 77 } 78 return $invoker; 79 } 80 81 /** 82 * Uses reflection to run every method within itself 83 * starting with the string "test" unless a method 84 * is specified. 85 * @param SimpleReporter $reporter Current test reporter. 86 * @access public 87 */ 88 function run($reporter) { 89 SimpleTest::setCurrent($this); 90 $this->_reporter = $reporter; 91 $this->_reporter->paintCaseStart($this->getLabel()); 92 foreach ($this->getTests() as $method) { 93 if ($this->_reporter->shouldInvoke($this->getLabel(), $method)) { 94 $invoker = $this->_reporter->createInvoker($this->createInvoker()); 95 $invoker->before($method); 96 $invoker->invoke($method); 97 $invoker->after($method); 98 } 99 } 100 $this->_reporter->paintCaseEnd($this->getLabel()); 101 unset($this->_reporter); 102 return $reporter->getStatus(); 103 } 104 105 /** 106 * Gets a list of test names. Normally that will 107 * be all internal methods that start with the 108 * name "test". This method should be overridden 109 * if you want a different rule. 110 * @return array List of test names. 111 * @access public 112 */ 113 function getTests() { 114 $methods = array(); 115 foreach (get_class_methods(get_class($this)) as $method) { 116 if ($this->_isTest($method)) { 117 $methods[] = $method; 118 } 119 } 120 return $methods; 121 } 122 123 /** 124 * Tests to see if the method is a test that should 125 * be run. Currently any method that starts with 'test' 126 * is a candidate unless it is the constructor. 127 * @param string $method Method name to try. 128 * @return boolean True if test method. 129 * @access protected 130 */ 131 function _isTest($method) { 132 if (strtolower(substr($method, 0, 4)) == 'test') { 133 return ! SimpleTestCompatibility::isA($this, strtolower($method)); 134 } 135 return false; 136 } 137 138 /** 139 * Announces the start of the test. 140 * @param string $method Test method just started. 141 * @access public 142 */ 143 function before($method) { 144 $this->_reporter->paintMethodStart($method); 145 $this->_observers = array(); 146 } 147 148 /** 149 * Sets up unit test wide variables at the start 150 * of each test method. To be overridden in 151 * actual user test cases. 152 * @access public 153 */ 154 function setUp() { 155 } 156 157 /** 158 * Clears the data set in the setUp() method call. 159 * To be overridden by the user in actual user test cases. 160 * @access public 161 */ 162 function tearDown() { 163 } 164 165 /** 166 * Announces the end of the test. Includes private clean up. 167 * @param string $method Test method just finished. 168 * @access public 169 */ 170 function after($method) { 171 for ($i = 0; $i < count($this->_observers); $i++) { 172 $this->_observers[$i]->atTestEnd($method); 173 } 174 $this->_reporter->paintMethodEnd($method); 175 } 176 177 /** 178 * Sets up an observer for the test end. 179 * @param object $observer Must have atTestEnd() 180 * method. 181 * @access public 182 */ 183 function tell($observer) { 184 $this->_observers[] = $observer; 185 } 186 187 /** 188 * Sends a pass event with a message. 189 * @param string $message Message to send. 190 * @access public 191 */ 192 function pass($message = "Pass") { 193 if (! isset($this->_reporter)) { 194 trigger_error('Can only make assertions within test methods'); 195 } 196 $this->_reporter->paintPass( 197 $message . $this->getAssertionLine()); 198 return true; 199 } 200 201 /** 202 * Sends a fail event with a message. 203 * @param string $message Message to send. 204 * @access public 205 */ 206 function fail($message = "Fail") { 207 if (! isset($this->_reporter)) { 208 trigger_error('Can only make assertions within test methods'); 209 } 210 $this->_reporter->paintFail( 211 $message . $this->getAssertionLine()); 212 return false; 213 } 214 215 /** 216 * Formats a PHP error and dispatches it to the 217 * reporter. 218 * @param integer $severity PHP error code. 219 * @param string $message Text of error. 220 * @param string $file File error occoured in. 221 * @param integer $line Line number of error. 222 * @access public 223 */ 224 function error($severity, $message, $file, $line) { 225 if (! isset($this->_reporter)) { 226 trigger_error('Can only make assertions within test methods'); 227 } 228 $this->_reporter->paintError( 229 "Unexpected PHP error [$message] severity [$severity] in [$file] line [$line]"); 230 } 231 232 /** 233 * Formats an exception and dispatches it to the 234 * reporter. 235 * @param Exception $exception Object thrown. 236 * @access public 237 */ 238 function exception($exception) { 239 $this->_reporter->paintError( 240 'Unexpected exception of type [' . get_class($exception) . 241 '] with message ['. $exception->getMessage() . 242 '] in ['. $exception->getFile() . 243 '] line [' . $exception->getLine() . ']'); 244 } 245 246 /** 247 * Sends a user defined event to the test reporter. 248 * This is for small scale extension where 249 * both the test case and either the reporter or 250 * display are subclassed. 251 * @param string $type Type of event. 252 * @param mixed $payload Object or message to deliver. 253 * @access public 254 */ 255 function signal($type, $payload) { 256 if (! isset($this->_reporter)) { 257 trigger_error('Can only make assertions within test methods'); 258 } 259 $this->_reporter->paintSignal($type, $payload); 260 } 261 262 /** 263 * Cancels any outstanding errors. 264 * @access public 265 */ 266 function swallowErrors() { 267 $queue = &SimpleErrorQueue::instance(); 268 $queue->clear(); 269 } 270 271 /** 272 * Runs an expectation directly, for extending the 273 * tests with new expectation classes. 274 * @param SimpleExpectation $expectation Expectation subclass. 275 * @param mixed $compare Value to compare. 276 * @param string $message Message to display. 277 * @return boolean True on pass 278 * @access public 279 */ 280 function assert($expectation, $compare, $message = '%s') { 281 return $this->assertTrue( 282 $expectation->test($compare), 283 sprintf($message, $expectation->overlayMessage($compare))); 284 } 285 286 /** 287 * @deprecated 288 */ 289 function assertExpectation($expectation, $compare, $message = '%s') { 290 return $this->assert($expectation, $compare, $message); 291 } 292 293 /** 294 * Called from within the test methods to register 295 * passes and failures. 296 * @param boolean $result Pass on true. 297 * @param string $message Message to display describing 298 * the test state. 299 * @return boolean True on pass 300 * @access public 301 */ 302 function assertTrue($result, $message = false) { 303 if (! $message) { 304 $message = 'True assertion got ' . ($result ? 'True' : 'False'); 305 } 306 if ($result) { 307 return $this->pass($message); 308 } else { 309 return $this->fail($message); 310 } 311 } 312 313 /** 314 * Will be true on false and vice versa. False 315 * is the PHP definition of false, so that null, 316 * empty strings, zero and an empty array all count 317 * as false. 318 * @param boolean $result Pass on false. 319 * @param string $message Message to display. 320 * @return boolean True on pass 321 * @access public 322 */ 323 function assertFalse($result, $message = false) { 324 if (! $message) { 325 $message = 'False assertion got ' . ($result ? 'True' : 'False'); 326 } 327 return $this->assertTrue(! $result, $message); 328 } 329 330 /** 331 * Uses a stack trace to find the line of an assertion. 332 * @param string $format String formatting. 333 * @param array $stack Stack frames top most first. Only 334 * needed if not using the PHP 335 * backtrace function. 336 * @return string Line number of first assert* 337 * method embedded in format string. 338 * @access public 339 */ 340 function getAssertionLine($stack = false) { 341 if ($stack === false) { 342 $stack = SimpleTestCompatibility::getStackTrace(); 343 } 344 return SimpleDumper::getFormattedAssertionLine($stack); 345 } 346 347 /** 348 * Sends a formatted dump of a variable to the 349 * test suite for those emergency debugging 350 * situations. 351 * @param mixed $variable Variable to display. 352 * @param string $message Message to display. 353 * @return mixed The original variable. 354 * @access public 355 */ 356 function dump($variable, $message = false) { 357 $formatted = SimpleDumper::dump($variable); 358 if ($message) { 359 $formatted = $message . "\n" . $formatted; 360 } 361 $this->_reporter->paintFormattedMessage($formatted); 362 return $variable; 363 } 364 365 /** 366 * Dispatches a text message straight to the 367 * test suite. Useful for status bar displays. 368 * @param string $message Message to show. 369 * @access public 370 */ 371 function sendMessage($message) { 372 $this->_reporter->PaintMessage($message); 373 } 374 375 /** 376 * Accessor for the number of subtests. 377 * @return integer Number of test cases. 378 * @access public 379 * @static 380 */ 381 static function getSize() { 382 return 1; 383 } 384 } 385 386 /** 387 * This is a composite test class for combining 388 * test cases and other RunnableTest classes into 389 * a group test. 390 * @package SimpleTest 391 * @subpackage UnitTester 392 */ 393 class GroupTest { 394 protected $_label; 395 protected $_test_cases; 396 protected $_old_track_errors; 397 protected $_xdebug_is_enabled; 398 399 /** 400 * Sets the name of the test suite. 401 * @param string $label Name sent at the start and end 402 * of the test. 403 * @access public 404 */ 405 function GroupTest($label = false) { 406 $this->_label = $label ? $label : get_class($this); 407 $this->_test_cases = array(); 408 $this->_old_track_errors = ini_get('track_errors'); 409 $this->_xdebug_is_enabled = function_exists('xdebug_is_enabled') ? 410 xdebug_is_enabled() : false; 411 } 412 413 /** 414 * Accessor for the test name for subclasses. 415 * @return string Name of the test. 416 * @access public 417 */ 418 function getLabel() { 419 return $this->_label; 420 } 421 422 function setLabel($value) 423 { 424 $this->_label = $value; 425 } 426 427 /** 428 * Adds a test into the suite. Can be either a group 429 * test or some other unit test. 430 * @param SimpleTestCase $test_case Suite or individual test 431 * case implementing the 432 * runnable test interface. 433 * @access public 434 */ 435 function addTestCase($test_case) { 436 $this->_test_cases[] = $test_case; 437 } 438 439 /** 440 * Adds a test into the suite by class name. The class will 441 * be instantiated as needed. 442 * @param SimpleTestCase $test_case Suite or individual test 443 * case implementing the 444 * runnable test interface. 445 * @access public 446 */ 447 function addTestClass($class) { 448 if ($this->_getBaseTestCase($class) == 'grouptest') { 449 $this->_test_cases[] = new $class(); 450 } else { 451 $this->_test_cases[] = $class; 452 } 453 } 454 455 /** 456 * Builds a group test from a library of test cases. 457 * The new group is composed into this one. 458 * @param string $test_file File name of library with 459 * test case classes. 460 * @access public 461 */ 462 function addTestFile($test_file) { 463 $existing_classes = get_declared_classes(); 464 if ($error = $this->_requireWithError($test_file)) { 465 $this->addTestCase(new BadGroupTest($test_file, $error)); 466 return; 467 } 468 $classes = $this->_selectRunnableTests($existing_classes, get_declared_classes()); 469 if (count($classes) == 0) { 470 $this->addTestCase(new BadGroupTest($test_file, "No runnable test cases in [$test_file]")); 471 return; 472 } 473 $group = $this->_createGroupFromClasses($test_file, $classes); 474 $this->addTestCase($group); 475 } 476 477 /** 478 * Requires a source file recording any syntax errors. 479 * @param string $file File name to require in. 480 * @return string/boolean An error message on failure or false 481 * if no errors. 482 * @access private 483 */ 484 function _requireWithError($file) { 485 $this->_enableErrorReporting(); 486 include_once($file); 487 $error = isset($php_errormsg) ? $php_errormsg : false; 488 $this->_disableErrorReporting(); 489 $self_inflicted_errors = array( 490 'Assigning the return value of new by reference is deprecated', 491 'var: Deprecated. Please use the public/private/protected modifiers'); 492 if (in_array($error, $self_inflicted_errors)) { 493 return false; 494 } 495 return $error; 496 } 497 498 /** 499 * Sets up detection of parse errors. Note that XDebug 500 * interferes with this and has to be disabled. This is 501 * to make sure the correct error code is returned 502 * from unattended scripts. 503 * @access private 504 */ 505 function _enableErrorReporting() { 506 if ($this->_xdebug_is_enabled) { 507 xdebug_disable(); 508 } 509 ini_set('track_errors', true); 510 } 511 512 /** 513 * Resets detection of parse errors to their old values. 514 * This is to make sure the correct error code is returned 515 * from unattended scripts. 516 * @access private 517 */ 518 function _disableErrorReporting() { 519 ini_set('track_errors', $this->_old_track_errors); 520 if ($this->_xdebug_is_enabled) { 521 xdebug_enable(); 522 } 523 } 524 525 /** 526 * Calculates the incoming test cases from a before 527 * and after list of loaded classes. Skips abstract 528 * classes. 529 * @param array $existing_classes Classes before require(). 530 * @param array $new_classes Classes after require(). 531 * @return array New classes which are test 532 * cases that shouldn't be ignored. 533 * @access private 534 */ 535 function _selectRunnableTests($existing_classes, $new_classes) { 536 $classes = array(); 537 foreach ($new_classes as $class) { 538 if (in_array($class, $existing_classes)) { 539 continue; 540 } 541 if ($this->_getBaseTestCase($class)) { 542 $reflection = new SimpleReflection($class); 543 if ($reflection->isAbstract()) { 544 SimpleTest::ignore($class); 545 } 546 $classes[] = $class; 547 } 548 } 549 return $classes; 550 } 551 552 /** 553 * Builds a group test from a class list. 554 * @param string $title Title of new group. 555 * @param array $classes Test classes. 556 * @return GroupTest Group loaded with the new 557 * test cases. 558 * @access private 559 */ 560 function &_createGroupFromClasses($title, $classes) { 561 SimpleTest::ignoreParentsIfIgnored($classes); 562 $group = new GroupTest($title); 563 foreach ($classes as $class) { 564 if (! SimpleTest::isIgnored($class)) { 565 $group->addTestClass($class); 566 } 567 } 568 return $group; 569 } 570 571 /** 572 * Test to see if a class is derived from the 573 * SimpleTestCase class. 574 * @param string $class Class name. 575 * @access private 576 */ 577 function _getBaseTestCase($class) { 578 while ($class = get_parent_class($class)) { 579 $class = strtolower($class); 580 if ($class == "simpletestcase" || $class == "grouptest") { 581 return $class; 582 } 583 } 584 return false; 585 } 586 587 /** 588 * Delegates to a visiting collector to add test 589 * files. 590 * @param string $path Path to scan from. 591 * @param SimpleCollector $collector Directory scanner. 592 * @access public 593 */ 594 function collect($path, $collector) { 595 $collector->collect($this, $path); 596 } 597 598 /** 599 * Invokes run() on all of the held test cases, instantiating 600 * them if necessary. 601 * @param SimpleReporter $reporter Current test reporter. 602 * @access public 603 */ 604 function run($reporter) { 605 $reporter->paintGroupStart($this->getLabel(), $this->getSize()); 606 for ($i = 0, $count = count($this->_test_cases); $i < $count; $i++) { 607 if (is_string($this->_test_cases[$i])) { 608 $class = $this->_test_cases[$i]; 609 $test = new $class(); 610 $test->run($reporter); 611 } else { 612 $this->_test_cases[$i]->run($reporter); 613 } 614 } 615 $reporter->paintGroupEnd($this->getLabel()); 616 return $reporter->getStatus(); 617 } 618 619 /** 620 * Number of contained test cases. 621 * @return integer Total count of cases in the group. 622 * @access public 623 */ 624 function getSize() { 625 $count = 0; 626 foreach ($this->_test_cases as $case) { 627 if (is_string($case)) { 628 $count++; 629 } else { 630 $count += $case->getSize(); 631 } 632 } 633 return $count; 634 } 635 } 636 637 /** 638 * This is a failing group test for when a test suite hasn't 639 * loaded properly. 640 * @package SimpleTest 641 * @subpackage UnitTester 642 */ 643 class BadGroupTest { 644 protected $_label; 645 protected $_error; 646 647 /** 648 * Sets the name of the test suite and error message. 649 * @param string $label Name sent at the start and end 650 * of the test. 651 * @access public 652 */ 653 function BadGroupTest($label, $error) { 654 $this->_label = $label; 655 $this->_error = $error; 656 } 657 658 /** 659 * Accessor for the test name for subclasses. 660 * @return string Name of the test. 661 * @access public 662 */ 663 function getLabel() { 664 return $this->_label; 665 } 666 667 /** 668 * Sends a single error to the reporter. 669 * @param SimpleReporter $reporter Current test reporter. 670 * @access public 671 */ 672 function run($reporter) { 673 $reporter->paintGroupStart($this->getLabel(), $this->getSize()); 674 $reporter->paintFail('Bad GroupTest [' . $this->getLabel() . 675 '] with error [' . $this->_error . ']'); 676 $reporter->paintGroupEnd($this->getLabel()); 677 return $reporter->getStatus(); 678 } 679 680 /** 681 * Number of contained test cases. Always zero. 682 * @return integer Total count of cases in the group. 683 * @access public 684 */ 685 function getSize() { 686 return 0; 687 } 688 } 689 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Sun Feb 25 21:07:04 2007 | par Balluche grâce à PHPXref 0.7 |