Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/lib/simpletestlib/test_case.php
Go to the documentation of this file.
00001 <?php
00013 require_once(dirname(__FILE__) . '/invoker.php');
00014 require_once(dirname(__FILE__) . '/errors.php');
00015 require_once(dirname(__FILE__) . '/compatibility.php');
00016 require_once(dirname(__FILE__) . '/scorer.php');
00017 require_once(dirname(__FILE__) . '/expectation.php');
00018 require_once(dirname(__FILE__) . '/dumper.php');
00019 require_once(dirname(__FILE__) . '/simpletest.php');
00020 if (version_compare(phpversion(), '5') >= 0) {
00021     require_once(dirname(__FILE__) . '/exceptions.php');
00022     require_once(dirname(__FILE__) . '/reflection_php5.php');
00023 } else {
00024     require_once(dirname(__FILE__) . '/reflection_php4.php');
00025 }
00026 if (! defined('SIMPLE_TEST')) {
00030     define('SIMPLE_TEST', dirname(__FILE__) . DIRECTORY_SEPARATOR);
00031 }
00042 class SimpleTestCase {
00043     var $_label = false;
00044     var $_reporter;
00045     var $_observers;
00046     var $_should_skip = false;
00047 
00054     function SimpleTestCase($label = false) {
00055         if ($label) {
00056             $this->_label = $label;
00057         }
00058     }
00059 
00065     function getLabel() {
00066         return $this->_label ? $this->_label : get_class($this);
00067     }
00068 
00075     function skip() {
00076     }
00077 
00085     function skipIf($should_skip, $message = '%s') {
00086         if ($should_skip && ! $this->_should_skip) {
00087             $this->_should_skip = true;
00088             $message = sprintf($message, 'Skipping [' . get_class($this) . ']');
00089             $this->_reporter->paintSkip($message . $this->getAssertionLine());
00090         }
00091     }
00092 
00100     function skipUnless($shouldnt_skip, $message = false) {
00101         $this->skipIf(! $shouldnt_skip, $message);
00102     }
00103 
00109     function &createInvoker() {
00110         $invoker = new SimpleErrorTrappingInvoker(new SimpleInvoker($this));
00111         if (version_compare(phpversion(), '5') >= 0) {
00112             $invoker = new SimpleExceptionTrappingInvoker($invoker);
00113         }
00114         return $invoker;
00115     }
00116 
00125     function run(&$reporter) {
00126         $context = &SimpleTest::getContext();
00127         $context->setTest($this);
00128         $context->setReporter($reporter);
00129         $this->_reporter = &$reporter;
00130         $started = false;
00131         foreach ($this->getTests() as $method) {
00132             if ($reporter->shouldInvoke($this->getLabel(), $method)) {
00133                 $this->skip();
00134                 if ($this->_should_skip) {
00135                     break;
00136                 }
00137                 if (! $started) {
00138                     $reporter->paintCaseStart($this->getLabel());
00139                     $started = true;
00140                 }
00141 //moodlefix begins
00142                 if (defined('TIME_ALLOWED_PER_UNIT_TEST')) {
00143                     set_time_limit(TIME_ALLOWED_PER_UNIT_TEST);
00144                 }
00145 //moodlefix ends
00146                 $invoker = &$this->_reporter->createInvoker($this->createInvoker());
00147                 $invoker->before($method);
00148                 $invoker->invoke($method);
00149                 $invoker->after($method);
00150             }
00151         }
00152         if ($started) {
00153             $reporter->paintCaseEnd($this->getLabel());
00154         }
00155         unset($this->_reporter);
00156 //moodlefix begins
00157         $context->unsetTest();
00158 //moodlefix ends
00159         return $reporter->getStatus();
00160     }
00161 
00170     function getTests() {
00171         $methods = array();
00172         foreach (get_class_methods(get_class($this)) as $method) {
00173             if ($this->_isTest($method)) {
00174                 $methods[] = $method;
00175             }
00176         }
00177         return $methods;
00178     }
00179 
00188     function _isTest($method) {
00189         if (strtolower(substr($method, 0, 4)) == 'test') {
00190             return ! SimpleTestCompatibility::isA($this, strtolower($method));
00191         }
00192         return false;
00193     }
00194 
00200     function before($method) {
00201         $this->_reporter->paintMethodStart($method);
00202         $this->_observers = array();
00203     }
00204 
00211     function setUp() {
00212     }
00213 
00219     function tearDown() {
00220     }
00221 
00227     function after($method) {
00228         for ($i = 0; $i < count($this->_observers); $i++) {
00229             $this->_observers[$i]->atTestEnd($method, $this);
00230         }
00231         $this->_reporter->paintMethodEnd($method);
00232     }
00233 
00240     function tell(&$observer) {
00241         $this->_observers[] = &$observer;
00242     }
00243 
00247     function pass($message = "Pass") {
00248         if (! isset($this->_reporter)) {
00249             trigger_error('Can only make assertions within test methods');
00250         }
00251         $this->_reporter->paintPass(
00252                 $message . $this->getAssertionLine());
00253         return true;
00254     }
00255 
00261     function fail($message = "Fail") {
00262         if (! isset($this->_reporter)) {
00263             trigger_error('Can only make assertions within test methods');
00264         }
00265         $this->_reporter->paintFail(
00266                 $message . $this->getAssertionLine());
00267         return false;
00268     }
00269 
00279     function error($severity, $message, $file, $line) {
00280         if (! isset($this->_reporter)) {
00281             trigger_error('Can only make assertions within test methods');
00282         }
00283         $this->_reporter->paintError(
00284                 "Unexpected PHP error [$message] severity [$severity] in [$file line $line]");
00285     }
00286 
00293     function exception($exception) {
00294         $this->_reporter->paintException($exception);
00295     }
00296 
00300     function signal($type, &$payload) {
00301         if (! isset($this->_reporter)) {
00302             trigger_error('Can only make assertions within test methods');
00303         }
00304         $this->_reporter->paintSignal($type, $payload);
00305     }
00306 
00316     function assert(&$expectation, $compare, $message = '%s') {
00317         if ($expectation->test($compare)) {
00318             return $this->pass(sprintf(
00319                     $message,
00320                     $expectation->overlayMessage($compare, $this->_reporter->getDumper())));
00321         } else {
00322             return $this->fail(sprintf(
00323                     $message,
00324                     $expectation->overlayMessage($compare, $this->_reporter->getDumper())));
00325         }
00326     }
00327 
00331     function assertExpectation(&$expectation, $compare, $message = '%s') {
00332         return $this->assert($expectation, $compare, $message);
00333     }
00334 
00341     function getAssertionLine() {
00342         $trace = new SimpleStackTrace(array('assert', 'expect', 'pass', 'fail', 'skip'));
00343         return $trace->traceMethod();
00344     }
00345 
00355     function dump($variable, $message = false) {
00356         $dumper = $this->_reporter->getDumper();
00357         $formatted = $dumper->dump($variable);
00358         if ($message) {
00359             $formatted = $message . "\n" . $formatted;
00360         }
00361         $this->_reporter->paintFormattedMessage($formatted);
00362         return $variable;
00363     }
00364 
00368     function sendMessage($message) {
00369         $this->_reporter->PaintMessage($message);
00370     }
00371 
00378     function getSize() {
00379         return 1;
00380     }
00381 }
00382 
00386 class SimpleFileLoader {
00387 
00396     function &load($test_file) {
00397         $existing_classes = get_declared_classes();
00398         $existing_globals = get_defined_vars();
00399         global $CFG;
00400         include_once($test_file);
00401         $new_globals = get_defined_vars();
00402         $this->_makeFileVariablesGlobal($existing_globals, $new_globals);
00403         $new_classes = array_diff(get_declared_classes(), $existing_classes);
00404         if (empty($new_classes)) {
00405             $new_classes = $this->_scrapeClassesFromFile($test_file);
00406         }
00407         $classes = $this->selectRunnableTests($new_classes);
00408         $suite = &$this->createSuiteFromClasses($test_file, $classes);
00409         return $suite;
00410     }
00411 
00418     function _makeFileVariablesGlobal($existing, $new) {
00419         $globals = array_diff(array_keys($new), array_keys($existing));
00420         foreach ($globals as $global) {
00421             $_GLOBALS[$global] = $new[$global];
00422         }
00423     }
00424 
00435     function _scrapeClassesFromFile($test_file) {
00436         preg_match_all('~^\s*class\s+(\w+)(\s+(extends|implements)\s+\w+)*\s*\{~mi',
00437                         file_get_contents($test_file),
00438                         $matches );
00439         return $matches[1];
00440     }
00441 
00450     function selectRunnableTests($candidates) {
00451         $classes = array();
00452         foreach ($candidates as $class) {
00453             if (TestSuite::getBaseTestCase($class)) {
00454                 $reflection = new SimpleReflection($class);
00455                 if ($reflection->isAbstract()) {
00456                     SimpleTest::ignore($class);
00457                 } else {
00458                     $classes[] = $class;
00459                 }
00460             }
00461         }
00462         return $classes;
00463     }
00464 
00473     function &createSuiteFromClasses($title, $classes) {
00474         if (count($classes) == 0) {
00475             $suite = new BadTestSuite($title, "No runnable test cases in [$title]");
00476             return $suite;
00477         }
00478         SimpleTest::ignoreParentsIfIgnored($classes);
00479         $suite = new TestSuite($title);
00480         foreach ($classes as $class) {
00481             if (! SimpleTest::isIgnored($class)) {
00482                 $suite->addTestClass($class);
00483             }
00484         }
00485         return $suite;
00486     }
00487 }
00488 
00496 class TestSuite {
00497     var $_label;
00498     var $_test_cases;
00499 
00506     function TestSuite($label = false) {
00507         $this->_label = $label;
00508         $this->_test_cases = array();
00509     }
00510 
00517     function getLabel() {
00518         if (! $this->_label) {
00519             return ($this->getSize() == 1) ?
00520                     get_class($this->_test_cases[0]) : get_class($this);
00521         } else {
00522             return $this->_label;
00523         }
00524     }
00525 
00529     function addTestCase(&$test_case) {
00530         $this->_test_cases[] = &$test_case;
00531     }
00532 
00536     function addTestClass($class) {
00537         if (TestSuite::getBaseTestCase($class) == 'testsuite') {
00538             $this->_test_cases[] = new $class();
00539         } else {
00540             $this->_test_cases[] = $class;
00541         }
00542     }
00543 
00552     function add(&$test_case) {
00553         if (! is_string($test_case)) {
00554             $this->_test_cases[] = &$test_case;
00555         } elseif (TestSuite::getBaseTestCase($class) == 'testsuite') {
00556             $this->_test_cases[] = new $class();
00557         } else {
00558             $this->_test_cases[] = $class;
00559         }
00560     }
00561 
00565     function addTestFile($test_file) {
00566         $this->addFile($test_file);
00567     }
00568 
00576     function addFile($test_file) {
00577         $extractor = new SimpleFileLoader();
00578         $this->add($extractor->load($test_file));
00579     }
00580 
00588     function collect($path, &$collector) {
00589         $collector->collect($this, $path);
00590     }
00591 
00598     function run(&$reporter) {
00599         $reporter->paintGroupStart($this->getLabel(), $this->getSize());
00600         for ($i = 0, $count = count($this->_test_cases); $i < $count; $i++) {
00601             if (is_string($this->_test_cases[$i])) {
00602                 $class = $this->_test_cases[$i];
00603                 // moodle hack start - need to do this before the constructor call, because of FakeDBUnitTestCase.
00604                 global $CFG;
00605                 if (is_subclass_of($class, 'FakeDBUnitTestCase')) {
00606                     // Do not execute this test because the test tables system no longer works, reporting it as exception
00607                     $reporter->paintError("Unit test \"{$class}\" of type FakeDBUnitTestCase no longer supported. Must be migrated to UnitTestCaseUsingDatabase.");
00608                     continue;
00609                 }
00610                 if (is_subclass_of($class, 'UnitTestCaseUsingDatabase') && empty($CFG->unittestprefix)) {
00611                     // Do not execute this test because $CFG->unittestprefix is not set, but it will be required.
00612                     $reporter->paintSkip("Unit test \"{$class}\" of type UnitTestCaseUsingDatabase skipped. Must define different, non-conflicting \$CFG->unittestprefix to be runnable.");
00613                     continue;
00614                 }
00615                 // moodle hack end
00616                 $test = new $class();
00617                 $test->run($reporter);
00618                 unset($test);
00619             } else {
00620                 $this->_test_cases[$i]->run($reporter);
00621             }
00622         }
00623         $reporter->paintGroupEnd($this->getLabel());
00624         return $reporter->getStatus();
00625     }
00626 
00632     function getSize() {
00633         $count = 0;
00634         foreach ($this->_test_cases as $case) {
00635             if (is_string($case)) {
00636                 if (! SimpleTest::isIgnored($case)) {
00637                     $count++;
00638                 }
00639             } else {
00640                 $count += $case->getSize();
00641             }
00642         }
00643         return $count;
00644     }
00645 
00653     function getBaseTestCase($class) {
00654         while ($class = get_parent_class($class)) {
00655             $class = strtolower($class);
00656             if ($class == 'simpletestcase' || $class == 'testsuite') {
00657                 return $class;
00658             }
00659         }
00660         return false;
00661     }
00662 }
00663 
00669 class GroupTest extends TestSuite {
00670     // moodle fix: adding old style constructor to make it compatible with PHP 5.3
00671     function GroupTest($label = false) {
00672         parent::TestSuite($label);
00673     }
00674 }
00675 
00682 class BadTestSuite {
00683     var $_label;
00684     var $_error;
00685 
00692     function BadTestSuite($label, $error) {
00693         $this->_label = $label;
00694         $this->_error = $error;
00695     }
00696 
00702     function getLabel() {
00703         return $this->_label;
00704     }
00705 
00711     function run(&$reporter) {
00712         $reporter->paintGroupStart($this->getLabel(), $this->getSize());
00713         $reporter->paintFail('Bad TestSuite [' . $this->getLabel() .
00714                 '] with error [' . $this->_error . ']');
00715         $reporter->paintGroupEnd($this->getLabel());
00716         return $reporter->getStatus();
00717     }
00718 
00724     function getSize() {
00725         return 0;
00726     }
00727 }
00728 
00734 class BadGroupTest extends BadTestSuite { }
00735 ?>
 All Data Structures Namespaces Files Functions Variables Enumerations