<?php /** * Base include file for SimpleTest * @package SimpleTest * @subpackage UnitTester * @version $Id: runner.php 1398 2006-09-08 19:31:03Z xue $ */ /**#@+ * Includes SimpleTest files and defined the root constant * for dependent libraries. */ require_once(dirname(__FILE__) . '/errors.php'); require_once(dirname(__FILE__) . '/options.php'); require_once(dirname(__FILE__) . '/scorer.php'); require_once(dirname(__FILE__) . '/expectation.php'); require_once(dirname(__FILE__) . '/dumper.php'); if (! defined('SIMPLE_TEST')) { define('SIMPLE_TEST', dirname(__FILE__) . '/'); } /**#@-*/ /** * This is called by the class runner to run a * single test method. Will also run the setUp() * and tearDown() methods. * @package SimpleTest * @subpackage UnitTester */ class SimpleInvoker { protected $_test_case; /** * Stashes the test case for later. * @param SimpleTestCase $test_case Test case to run. */ function SimpleInvoker($test_case) { $this->_test_case = $test_case; } /** * Accessor for test case being run. * @return SimpleTestCase Test case. * @access public */ function getTestCase() { return $this->_test_case; } /** * Invokes a test method and buffered with setUp() * and tearDown() calls. * @param string $method Test method to call. * @access public */ function invoke($method) { $this->_test_case->setUp(); $this->_test_case->$method(); $this->_test_case->tearDown(); } } /** * Do nothing decorator. Just passes the invocation * straight through. * @package SimpleTest * @subpackage UnitTester */ class SimpleInvokerDecorator { protected $_invoker; /** * Stores the invoker to wrap. * @param SimpleInvoker $invoker Test method runner. */ function SimpleInvokerDecorator($invoker) { $this->_invoker = $invoker; } /** * Accessor for test case being run. * @return SimpleTestCase Test case. * @access public */ function getTestCase() { return $this->_invoker->getTestCase(); } /** * Invokes a test method and buffered with setUp() * and tearDown() calls. * @param string $method Test method to call. * @access public */ function invoke($method) { $this->_invoker->invoke($method); } } /** * Extension that traps errors into an error queue. * @package SimpleTest * @subpackage UnitTester */ class SimpleErrorTrappingInvoker extends SimpleInvokerDecorator { /** /** * Stores the invoker to wrap. * @param SimpleInvoker $invoker Test method runner. */ function SimpleErrorTrappingInvoker($invoker) { $this->SimpleInvokerDecorator($invoker); } /** * Invokes a test method and dispatches any * untrapped errors. Called back from * the visiting runner. * @param string $method Test method to call. * @access public */ function invoke($method) { set_error_handler('simpleTestErrorHandler'); parent::invoke($method); $queue = SimpleErrorQueue::instance(); while (list($severity, $message, $file, $line, $globals) = $queue->extract()) { $test_case = $this->getTestCase(); $test_case->error($severity, $message, $file, $line, $globals); } restore_error_handler(); } } /** * The standard runner. Will run every method starting * with test Basically the * Mediator pattern. * @package SimpleTest * @subpackage UnitTester */ class SimpleRunner { protected $_test_case; protected $_scorer; /** * Takes in the test case and reporter to mediate between. * @param SimpleTestCase $test_case Test case to run. * @param SimpleScorer $scorer Reporter to receive events. */ function SimpleRunner($test_case, $scorer) { $this->_test_case = $test_case; $this->_scorer = $scorer; } /** * Accessor for test case being run. * @return SimpleTestCase Test case. * @access public */ function getTestCase() { return $this->_test_case; } /** * Runs the test methods in the test case. * @param SimpleTest $test_case Test case to run test on. * @param string $method Name of test method. * @access public */ function run() { $methods = get_class_methods(get_class($this->_test_case)); $invoker = $this->_test_case->createInvoker(); foreach ($methods as $method) { if (! $this->_isTest($method)) { continue; } if ($this->_isConstructor($method)) { continue; } $this->_scorer->paintMethodStart($method); if ($this->_scorer->shouldInvoke($this->_test_case->getLabel(), $method)) { $invoker->invoke($method); } $this->_scorer->paintMethodEnd($method); } } /** * Tests to see if the method is the constructor and * so should be ignored. * @param string $method Method name to try. * @return boolean True if constructor. * @access protected */ function _isConstructor($method) { return SimpleTestCompatibility::isA( $this->_test_case, strtolower($method)); } /** * Tests to see if the method is a test that should * be run. Currently any method that starts with 'test' * is a candidate. * @param string $method Method name to try. * @return boolean True if test method. * @access protected */ function _isTest($method) { return strtolower(substr($method, 0, 4)) == 'test'; } /** * Paints the start of a test method. * @param string $test_name Name of test or other label. * @access public */ function paintMethodStart($test_name) { $this->_scorer->paintMethodStart($test_name); } /** * Paints the end of a test method. * @param string $test_name Name of test or other label. * @access public */ function paintMethodEnd($test_name) { $this->_scorer->paintMethodEnd($test_name); } /** * Chains to the wrapped reporter. * @param string $message Message is ignored. * @access public */ function paintPass($message) { $this->_scorer->paintPass($message); } /** * Chains to the wrapped reporter. * @param string $message Message is ignored. * @access public */ function paintFail($message) { $this->_scorer->paintFail($message); } /** * Chains to the wrapped reporter. * @param string $message Text of error formatted by * the test case. * @access public */ function paintError($message) { $this->_scorer->paintError($message); } /** * Chains to the wrapped reporter. * @param Exception $exception Object thrown. * @access public */ function paintException($exception) { $this->_scorer->paintException($exception); } /** * Chains to the wrapped reporter. * @param string $message Text to display. * @access public */ function paintMessage($message) { $this->_scorer->paintMessage($message); } /** * Chains to the wrapped reporter. * @param string $message Text to display. * @access public */ function paintFormattedMessage($message) { $this->_scorer->paintFormattedMessage($message); } /** * Chains to the wrapped reporter. * @param string $type Event type as text. * @param mixed $payload Message or object. * @return boolean Should return false if this * type of signal should fail the * test suite. * @access public */ function paintSignal($type, $payload) { $this->_scorer->paintSignal($type, $payload); } }