getParentClass()) { SimpleTest::ignore($parent->getName()); } } } } /** * Puts the object to the global pool of 'preferred' objects * which can be retrieved with SimpleTest :: preferred() method. * Instances of the same class are overwritten. * @param object $object Preferred object * @static * @access public * @see preferred() */ function prefer(&$object) { $registry = &SimpleTest::_getRegistry(); $registry['Preferred'][] = &$object; } /** * Retrieves 'preferred' objects from global pool. Class filter * can be applied in order to retrieve the object of the specific * class * @param array|string $classes Allowed classes or interfaces. * @static * @access public * @return array|object|null * @see prefer() */ function &preferred($classes) { if (! is_array($classes)) { $classes = array($classes); } $registry = &SimpleTest::_getRegistry(); for ($i = count($registry['Preferred']) - 1; $i >= 0; $i--) { foreach ($classes as $class) { if (is_a($registry['Preferred'][$i], $class)) { return $registry['Preferred'][$i]; } } } return null; } /** * Test to see if a test case is in the ignore * list. Quite obviously the ignore list should * be a separate object and will be one day. * This method is internal to SimpleTest. Don't * use it. * @param string $class Class name to test. * @return boolean True if should not be run. * @access public * @static */ function isIgnored($class) { $registry = &SimpleTest::_getRegistry(); return isset($registry['IgnoreList'][strtolower($class)]); } /** * Sets proxy to use on all requests for when * testing from behind a firewall. Set host * to false to disable. This will take effect * if there are no other proxy settings. * @param string $proxy Proxy host as URL. * @param string $username Proxy username for authentication. * @param string $password Proxy password for authentication. * @access public */ function useProxy($proxy, $username = false, $password = false) { $registry = &SimpleTest::_getRegistry(); $registry['DefaultProxy'] = $proxy; $registry['DefaultProxyUsername'] = $username; $registry['DefaultProxyPassword'] = $password; } /** * Accessor for default proxy host. * @return string Proxy URL. * @access public */ function getDefaultProxy() { $registry = &SimpleTest::_getRegistry(); return $registry['DefaultProxy']; } /** * Accessor for default proxy username. * @return string Proxy username for authentication. * @access public */ function getDefaultProxyUsername() { $registry = &SimpleTest::_getRegistry(); return $registry['DefaultProxyUsername']; } /** * Accessor for default proxy password. * @return string Proxy password for authentication. * @access public */ function getDefaultProxyPassword() { $registry = &SimpleTest::_getRegistry(); return $registry['DefaultProxyPassword']; } /** * Accessor for global registry of options. * @return hash All stored values. * @access private * @static */ function &_getRegistry() { static $registry = false; if (! $registry) { $registry = SimpleTest::_getDefaults(); } return $registry; } /** * Accessor for the context of the current * test run. * @return SimpleTestContext Current test run. * @access public * @static */ function &getContext() { static $context = false; if (! $context) { $context = new SimpleTestContext(); } return $context; } /** * Constant default values. * @return hash All registry defaults. * @access private * @static */ function _getDefaults() { return array( 'StubBaseClass' => 'SimpleStub', 'MockBaseClass' => 'SimpleMock', 'IgnoreList' => array(), 'DefaultProxy' => false, 'DefaultProxyUsername' => false, 'DefaultProxyPassword' => false, 'Preferred' => array(new HtmlReporter(), new TextReporter(), new XmlReporter())); } } /** * Container for all components for a specific * test run. Makes things like error queues * available to PHP event handlers, and also * gets around some nasty reference issues in * the mocks. * @package SimpleTest */ class SimpleTestContext { var $_test; var $_reporter; var $_resources; /** * Clears down the current context. * @access public */ function clear() { $this->_resources = array(); } /** * Sets the current test case instance. This * global instance can be used by the mock objects * to send message to the test cases. * @param SimpleTestCase $test Test case to register. * @access public */ function setTest(&$test) { $this->clear(); $this->_test = &$test; } /** * Accessor for currently running test case. * @return SimpleTestCase Current test. * @access public */ function &getTest() { return $this->_test; } /** * Sets the current reporter. This * global instance can be used by the mock objects * to send messages. * @param SimpleReporter $reporter Reporter to register. * @access public */ function setReporter(&$reporter) { $this->clear(); $this->_reporter = &$reporter; } /** * Accessor for current reporter. * @return SimpleReporter Current reporter. * @access public */ function &getReporter() { return $this->_reporter; } /** * Accessor for the Singleton resource. * @return object Global resource. * @access public * @static */ function &get($resource) { if (! isset($this->_resources[$resource])) { $this->_resources[$resource] = &new $resource(); } return $this->_resources[$resource]; } } /** * Interrogates the stack trace to recover the * failure point. */ class SimpleStackTrace { var $_prefixes; /** * Stashes the list of target prefixes. * @param array $prefixes List of method prefixes * to search for. */ function SimpleStackTrace($prefixes) { $this->_prefixes = $prefixes; } /** * Extracts the last method name that was not within * Simpletest itself. Captures a stack trace if none given. * @param array $stack List of stack frames. * @return string Snippet of test report with line * number and file. * @access public */ function traceMethod($stack = false) { $stack = $stack ? $stack : $this->_captureTrace(); foreach ($stack as $frame) { if ($this->_frameLiesWithinSimpleTestFolder($frame)) { continue; } if ($this->_frameMatchesPrefix($frame)) { return ' at [' . $frame['file'] . ' line ' . $frame['line'] . ']'; } } return ''; } /** * Test to see if error is generated by SimpleTest itself. * @param array $frame PHP stack frame. * @return boolean True if a SimpleTest file. * @access private */ function _frameLiesWithinSimpleTestFolder($frame) { if (isset($frame['file'])) { $path = dirname(__FILE__); if (strpos($frame['file'], $path) === 0) { if (dirname($frame['file']) == $path) { return true; } } } return false; } /** * Tries to determine if the method call is an assert, etc. * @param array $frame PHP stack frame. * @return boolean True if matches a target. * @access private */ function _frameMatchesPrefix($frame) { foreach ($this->_prefixes as $prefix) { if (strncmp($frame['function'], $prefix, strlen($prefix)) == 0) { return true; } } return false; } /** * Grabs a current stack trace. * @return array Fulle trace. * @access private */ function _captureTrace() { if (function_exists('debug_backtrace')) { return array_reverse(debug_backtrace()); } return array(); } }