[limb-svn] r6257 - 3.x/trunk/limb/tests_runner/lib/simpletest

svn at limb-project.com svn at limb-project.com
Mon Sep 3 14:41:33 MSD 2007


Author: pachanga
Date: 2007-09-03 14:41:32 +0400 (Mon, 03 Sep 2007)
New Revision: 6257
URL: http://fisheye.limb-project.com/changelog/limb/?cs=6257

Modified:
   3.x/trunk/limb/tests_runner/lib/simpletest/reflection_php5.php
   3.x/trunk/limb/tests_runner/lib/simpletest/test_case.php
Log:
-- porting some stuff(but not all, since there are some quite incompatible changes) from CVS, namely, fixing abstract classes related bugs

Modified: 3.x/trunk/limb/tests_runner/lib/simpletest/reflection_php5.php
===================================================================
--- 3.x/trunk/limb/tests_runner/lib/simpletest/reflection_php5.php	2007-09-02 19:00:06 UTC (rev 6256)
+++ 3.x/trunk/limb/tests_runner/lib/simpletest/reflection_php5.php	2007-09-03 10:41:32 UTC (rev 6257)
@@ -1,371 +1,372 @@
-<?php
-/**
- *	base include file for SimpleTest
- *	@package	SimpleTest
- *	@subpackage	UnitTester
- *	@version	$Id$
- */
-
-/**
- *    Version specific reflection API.
- *    @package SimpleTest
- *    @subpackage UnitTester
- */
-class SimpleReflection {
-	var $_interface;
-
-	/**
-	 *    Stashes the class/interface.
-	 *    @param string $interface    Class or interface
-	 *                                to inspect.
-	 */
-	function SimpleReflection($interface) {
-		$this->_interface = $interface;
-	}
-
-	/**
-	 *    Checks that a class has been declared. Versions
-	 *    before PHP5.0.2 need a check that it's not really
-	 *    an interface.
-	 *    @return boolean            True if defined.
-	 *    @access public
-	 */
-	function classExists() {
-		if (! class_exists($this->_interface)) {
-			return false;
-		}
-		$reflection = new ReflectionClass($this->_interface);
-		return ! $reflection->isInterface();
-	}
-
-	/**
-	 *    Needed to kill the autoload feature in PHP5
-	 *    for classes created dynamically.
-	 *    @return boolean        True if defined.
-	 *    @access public
-	 */
-	function classExistsSansAutoload() {
-		return class_exists($this->_interface, false);
-	}
-
-	/**
-	 *    Checks that a class or interface has been
-	 *    declared.
-	 *    @return boolean            True if defined.
-	 *    @access public
-	 */
-	function classOrInterfaceExists() {
-		return $this->_classOrInterfaceExistsWithAutoload($this->_interface, true);
-	}
-
-	/**
-	 *    Needed to kill the autoload feature in PHP5
-	 *    for classes created dynamically.
-	 *    @return boolean        True if defined.
-	 *    @access public
-	 */
-	function classOrInterfaceExistsSansAutoload() {
-		return $this->_classOrInterfaceExistsWithAutoload($this->_interface, false);
-	}
-
-	/**
-	 *    Needed to select the autoload feature in PHP5
-	 *    for classes created dynamically.
-	 *    @param string $interface       Class or interface name.
-	 *    @param boolean $autoload       True totriggerautoload.
-	 *    @return boolean                True if interface defined.
-	 *    @access private
-	 */
-	function _classOrInterfaceExistsWithAutoload($interface, $autoload) {
-		if (function_exists('interface_exists')) {
-			if (interface_exists($this->_interface, $autoload)) {
-				return true;
-			}
-		}
-		return class_exists($this->_interface, $autoload);
-	}
-
-	/**
-	 *    Gets the list of methods on a class or
-	 *    interface.
-	 *    @returns array              List of method names.
-	 *    @access public
-	 */
-	function getMethods() {
-		return array_unique(get_class_methods($this->_interface));
-	}
-
-	/**
-	 *    Gets the list of interfaces from a class. If the
-	 *    class name is actually an interface then just that
-	 *    interface is returned.
-	 *    @returns array          List of interfaces.
-	 *    @access public
-	 */
-	function getInterfaces() {
-		$reflection = new ReflectionClass($this->_interface);
-		if ($reflection->isInterface()) {
-			return array($this->_interface);
-		}
-		return $this->_onlyParents($reflection->getInterfaces());
-	}
-
-	/**
-	 *    Gets the list of methods for the implemented
-	 *    interfaces only.
-	 *    @returns array      List of enforced method signatures.
-	 *    @access public
-	 */
-	function getInterfaceMethods() {
-		$methods = array();
-		foreach ($this->getInterfaces() as $interface) {
-			$methods = array_merge($methods, get_class_methods($interface));
-		}
-		return array_unique($methods);
-	}
-
-	/**
-	 *    Checks to see if the method signature has to be tightly
-	 *    specified.
-	 *    @param string $method        Method name.
-	 *    @returns boolean             True if enforced.
-	 *    @access private
-	 */
-	function _isInterfaceMethod($method) {
-		return in_array($method, $this->getInterfaceMethods());
-	}
-
-	/**
-	 *    Finds the parent class name.
-	 *    @returns string      Parent class name.
-	 *    @access public
-	 */
-	function getParent() {
-		$reflection = new ReflectionClass($this->_interface);
-		$parent = $reflection->getParentClass();
-		if ($parent) {
-			return $parent->getName();
-		}
-		return false;
-	}
-
-	/**
-	 *    Trivially determines if the class is abstract.
-	 *    @returns boolean      True if abstract.
-	 *    @access public
-	 */
-	function isAbstract() {
-		$reflection = new ReflectionClass($this->_interface);
-		return $reflection->isAbstract();
-	}
-
-	/**
-	 *    Trivially determines if the class is an interface.
-	 *    @returns boolean      True if interface.
-	 *    @access public
-	 */
-	function isInterface() {
-		$reflection = new ReflectionClass($this->_interface);
-		return $reflection->isInterface();
-	}
-
-	/**
-	 *	  Scans for final methods, as they screw up inherited
-	 *    mocks by not allowing you to override them.
-	 *    @returns boolean   True if the class has a final method.
-	 *    @access public
-	 */
-	function hasFinal() {
-		$reflection = new ReflectionClass($this->_interface);
-		foreach ($reflection->getMethods() as $method) {
-			if ($method->isFinal()) {
-				return true;
-			}
-		}
-		return false;
-	}
-
-	/**
-	 *    Whittles a list of interfaces down to only the
-	 *    necessary top level parents.
-	 *    @param array $interfaces     Reflection API interfaces
-	 *                                 to reduce.
-	 *    @returns array               List of parent interface names.
-	 *    @access private
-	 */
-	function _onlyParents($interfaces) {
-		$parents = array();
-		$blacklist = array();
-		foreach ($interfaces as $interface) {
-			foreach($interfaces as $possible_parent) {
-				if ($interface->getName() == $possible_parent->getName()) {
-					continue;
-				}
-				if ($interface->isSubClassOf($possible_parent)) {
-					$blacklist[$possible_parent->getName()] = true;
-				}
-			}
-			if (!isset($blacklist[$interface->getName()])) {
-				$parents[] = $interface->getName();
-			}
-		}
-		return $parents;
-	}
-
-    /**
-     * Checks whether a method is abstract or not.
-     *
-     * @param   string   $name  Method name.
-     * @return  bool            true if method is abstract, else false
-     * @access  private
-     */
-    function _isAbstractMethod($name) {
-        $interface = new ReflectionClass($this->_interface);
-        if (! $interface->hasMethod($name)) {
-            return false;
-        }
-        return $interface->getMethod($name)->isAbstract();
-	}
-
-    /**
-     * Checks whether a method is abstract in parent or not.
-     *
-     * @param   string   $name  Method name.
-     * @return  bool            true if method is abstract in parent, else false
-     * @access  private
-     */
-    function _isAbstractMethodInParent($name) {
-        $interface = new ReflectionClass($this->_interface);
-        if (! $parent = $interface->getParentClass()) {
-            return false;
-        }
-        if (! $parent->hasMethod($name)) {
-            return false;
-        }
-        return $parent->getMethod($name)->isAbstract();
-	}
-
-	/**
-	 * Checks whether a method is static or not.
-	 *
-	 * @param	string	$name	Method name
-	 * @return	bool			true if method is static, else false
-	 * @access	private
-	 */
-	function _isStaticMethod($name) {
-		$interface = new ReflectionClass($this->_interface);
-		if (! $interface->hasMethod($name)) {
-			return false;
-		}
-		return $interface->getMethod($name)->isStatic();
-	}
-
-	/**
-	 *    Gets the source code matching the declaration
-	 *    of a method.
-	 *    @param string $name    Method name.
-	 *    @return string         Method signature up to last
-	 *                           bracket.
-	 *    @access public
-	 */
-	function getSignature($name) {
-		if ($name == '__set') {
-			return 'function __set($key, $value)';
-		}
-		if ($name == '__call') {
-			return 'function __call($method, $arguments)';
-		}
-		if (version_compare(phpversion(), '5.1.0', '>=')) {
-			if (in_array($name, array('__get', '__isset', $name == '__unset'))) {
-				return "function {$name}(\$key)";
-			}
-		}
-		// second check is required because methods can be protected abstract
-		// which means they are not callable, but need a complete signature
-		if (! is_callable(array($this->_interface, $name)) && ! $this->_isAbstractMethod($name)) {
-			return "function $name()";
-		}
-		if ($this->_isInterfaceMethod($name) ||
-            $this->_isAbstractMethod($name) ||
-            $this->_isAbstractMethodInParent($name) ||
-            $this->_isStaticMethod($name)) {
-			return $this->_getFullSignature($name);
-		}
-		return "function $name()";
-	}
-
-	/**
-	 *    For a signature specified in an interface, full
-	 *    details must be replicated to be a valid implementation.
-	 *    @param string $name    Method name.
-	 *    @return string         Method signature up to last
-	 *                           bracket.
-	 *    @access private
-	 */
-	function _getFullSignature($name) {
-		$interface = new ReflectionClass($this->_interface);
-		$method = $interface->getMethod($name);
-		$reference = $method->returnsReference() ? '&' : '';
-		$static = $method->isStatic() ? 'static ' : '';
-		return "{$static}function $reference$name(" .
-				implode(', ', $this->_getParameterSignatures($method)) .
-				")";
-	}
-
-	/**
-	 *    Gets the source code for each parameter.
-	 *    @param ReflectionMethod $method   Method object from
-	 *					                    reflection API
-	 *    @return array                     List of strings, each
-	 *                                      a snippet of code.
-	 *    @access private
-	 */
-	function _getParameterSignatures($method) {
-		$signatures = array();
-		foreach ($method->getParameters() as $parameter) {
-			$signature = '';
-			$type = $parameter->getClass();
-			if (is_null($type) && version_compare(phpversion(), '5.1.0', '>=') && $parameter->isArray()) {
-				$signature .= 'array ';
-			} elseif (!is_null($type)) {
-				$signature .= $type->getName() . ' ';
-			}
-			if ($parameter->isPassedByReference()) {
-				$signature .= '&';
-			}
-			$signature .= '$' . $this->_suppressSpurious($parameter->getName());
-			if ($this->_isOptional($parameter)) {
-				$signature .= ' = null';
-			}
-			$signatures[] = $signature;
-		}
-		return $signatures;
-	}
-
-	/**
-	 *    The SPL library has problems with the
-	 *    Reflection library. In particular, you can
-	 *    get extra characters in parameter names :(.
-	 *    @param string $name    Parameter name.
-	 *    @return string         Cleaner name.
-	 *    @access private
-	 */
-	function _suppressSpurious($name) {
-		return str_replace(array('[', ']', ' '), '', $name);
-	}
-
-	/**
-	 *    Test of a reflection parameter being optional
-	 *    that works with early versions of PHP5.
-	 *    @param reflectionParameter $parameter    Is this optional.
-	 *    @return boolean                          True if optional.
-	 *    @access private
-	 */
-	function _isOptional($parameter) {
-		if (method_exists($parameter, 'isOptional')) {
-			return $parameter->isOptional();
-		}
-		return false;
-	}
-}
-?>
\ No newline at end of file
+<?php
+/**
+ *	base include file for SimpleTest
+ *	@package	SimpleTest
+ *	@subpackage	UnitTester
+ *	@version	$Id$
+ */
+
+/**
+ *    Version specific reflection API.
+ *    @package SimpleTest
+ *    @subpackage UnitTester
+ */
+class SimpleReflection {
+	var $_interface;
+
+	/**
+	 *    Stashes the class/interface.
+	 *    @param string $interface    Class or interface
+	 *                                to inspect.
+	 */
+	function SimpleReflection($interface) {
+		$this->_interface = $interface;
+	}
+
+	/**
+	 *    Checks that a class has been declared. Versions
+	 *    before PHP5.0.2 need a check that it's not really
+	 *    an interface.
+	 *    @return boolean            True if defined.
+	 *    @access public
+	 */
+	function classExists() {
+		if (! class_exists($this->_interface)) {
+			return false;
+		}
+		$reflection = new ReflectionClass($this->_interface);
+		return ! $reflection->isInterface();
+	}
+
+	/**
+	 *    Needed to kill the autoload feature in PHP5
+	 *    for classes created dynamically.
+	 *    @return boolean        True if defined.
+	 *    @access public
+	 */
+	function classExistsSansAutoload() {
+		return class_exists($this->_interface, false);
+	}
+
+	/**
+	 *    Checks that a class or interface has been
+	 *    declared.
+	 *    @return boolean            True if defined.
+	 *    @access public
+	 */
+	function classOrInterfaceExists() {
+		return $this->_classOrInterfaceExistsWithAutoload($this->_interface, true);
+	}
+
+	/**
+	 *    Needed to kill the autoload feature in PHP5
+	 *    for classes created dynamically.
+	 *    @return boolean        True if defined.
+	 *    @access public
+	 */
+	function classOrInterfaceExistsSansAutoload() {
+		return $this->_classOrInterfaceExistsWithAutoload($this->_interface, false);
+	}
+
+	/**
+	 *    Needed to select the autoload feature in PHP5
+	 *    for classes created dynamically.
+	 *    @param string $interface       Class or interface name.
+	 *    @param boolean $autoload       True totriggerautoload.
+	 *    @return boolean                True if interface defined.
+	 *    @access private
+	 */
+	function _classOrInterfaceExistsWithAutoload($interface, $autoload) {
+		if (function_exists('interface_exists')) {
+			if (interface_exists($this->_interface, $autoload)) {
+				return true;
+			}
+		}
+		return class_exists($this->_interface, $autoload);
+	}
+
+	/**
+	 *    Gets the list of methods on a class or
+	 *    interface.
+	 *    @returns array              List of method names.
+	 *    @access public
+	 */
+	function getMethods() {
+		return array_unique(get_class_methods($this->_interface));
+	}
+
+	/**
+	 *    Gets the list of interfaces from a class. If the
+	 *    class name is actually an interface then just that
+	 *    interface is returned.
+	 *    @returns array          List of interfaces.
+	 *    @access public
+	 */
+	function getInterfaces() {
+		$reflection = new ReflectionClass($this->_interface);
+		if ($reflection->isInterface()) {
+			return array($this->_interface);
+		}
+		return $this->_onlyParents($reflection->getInterfaces());
+	}
+
+	/**
+	 *    Gets the list of methods for the implemented
+	 *    interfaces only.
+	 *    @returns array      List of enforced method signatures.
+	 *    @access public
+	 */
+	function getInterfaceMethods() {
+		$methods = array();
+		foreach ($this->getInterfaces() as $interface) {
+			$methods = array_merge($methods, get_class_methods($interface));
+		}
+		return array_unique($methods);
+	}
+
+	/**
+	 *    Checks to see if the method signature has to be tightly
+	 *    specified.
+	 *    @param string $method        Method name.
+	 *    @returns boolean             True if enforced.
+	 *    @access private
+	 */
+	function _isInterfaceMethod($method) {
+		return in_array($method, $this->getInterfaceMethods());
+	}
+
+	/**
+	 *    Finds the parent class name.
+	 *    @returns string      Parent class name.
+	 *    @access public
+	 */
+	function getParent() {
+		$reflection = new ReflectionClass($this->_interface);
+		$parent = $reflection->getParentClass();
+		if ($parent) {
+			return $parent->getName();
+		}
+		return false;
+	}
+
+	/**
+	 *    Trivially determines if the class is abstract.
+	 *    @returns boolean      True if abstract.
+	 *    @access public
+	 */
+	function isAbstract() {
+		$reflection = new ReflectionClass($this->_interface);
+		return $reflection->isAbstract();
+	}
+
+	/**
+	 *    Trivially determines if the class is an interface.
+	 *    @returns boolean      True if interface.
+	 *    @access public
+	 */
+	function isInterface() {
+		$reflection = new ReflectionClass($this->_interface);
+		return $reflection->isInterface();
+	}
+
+	/**
+	 *	  Scans for final methods, as they screw up inherited
+	 *    mocks by not allowing you to override them.
+	 *    @returns boolean   True if the class has a final method.
+	 *    @access public
+	 */
+	function hasFinal() {
+		$reflection = new ReflectionClass($this->_interface);
+		foreach ($reflection->getMethods() as $method) {
+			if ($method->isFinal()) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 *    Whittles a list of interfaces down to only the
+	 *    necessary top level parents.
+	 *    @param array $interfaces     Reflection API interfaces
+	 *                                 to reduce.
+	 *    @returns array               List of parent interface names.
+	 *    @access private
+	 */
+	function _onlyParents($interfaces) {
+		$parents = array();
+		$blacklist = array();
+		foreach ($interfaces as $interface) {
+			foreach($interfaces as $possible_parent) {
+				if ($interface->getName() == $possible_parent->getName()) {
+					continue;
+				}
+				if ($interface->isSubClassOf($possible_parent)) {
+					$blacklist[$possible_parent->getName()] = true;
+				}
+			}
+			if (!isset($blacklist[$interface->getName()])) {
+				$parents[] = $interface->getName();
+			}
+		}
+		return $parents;
+	}
+
+    /**
+     * Checks whether a method is abstract or not.
+     * @param   string   $name  Method name.
+     * @return  bool            true if method is abstract, else false
+     * @access  private
+     */
+    function _isAbstractMethod($name) {
+        $interface = new ReflectionClass($this->_interface);
+        if (! $interface->hasMethod($name)) {
+            return false;
+        }
+        return $interface->getMethod($name)->isAbstract();
+	}
+
+    /**
+     * Checks whether a method is abstract in all parents or not.
+     * @param   string   $name  Method name.
+     * @return  bool            true if method is abstract in parent, else false
+     * @access  private
+     */
+    function _isAbstractMethodInParents($name) {
+        $interface = new ReflectionClass($this->_interface);
+        $parent = $interface->getParentClass();
+        while($parent) {
+            if (! $parent->hasMethod($name)) {
+                return false;
+            }
+            if ($parent->getMethod($name)->isAbstract()) {
+                return true;
+            }
+            $parent = $parent->getParentClass();
+        }
+        return false;
+	}
+
+	/**
+	 * Checks whether a method is static or not.
+	 * @param	string	$name	Method name
+	 * @return	bool			true if method is static, else false
+	 * @access	private
+	 */
+	function _isStaticMethod($name) {
+		$interface = new ReflectionClass($this->_interface);
+		if (! $interface->hasMethod($name)) {
+			return false;
+		}
+		return $interface->getMethod($name)->isStatic();
+	}
+
+	/**
+	 *    Gets the source code matching the declaration
+	 *    of a method.
+	 *    @param string $name    Method name.
+	 *    @return string         Method signature up to last
+	 *                           bracket.
+	 *    @access public
+	 */
+	function getSignature($name) {
+		if ($name == '__set') {
+			return 'function __set($key, $value)';
+		}
+		if ($name == '__call') {
+			return 'function __call($method, $arguments)';
+		}
+		if (version_compare(phpversion(), '5.1.0', '>=')) {
+			if (in_array($name, array('__get', '__isset', $name == '__unset'))) {
+				return "function {$name}(\$key)";
+			}
+		}
+		if (! is_callable(array($this->_interface, $name)) && 
+        ! $this->_isAbstractMethod($name) && 
+        ! $this->_isAbstractMethodInParents($name)) {
+			return "function $name()";
+		}
+		if ($this->_isInterfaceMethod($name) ||
+				$this->_isAbstractMethod($name) ||
+				$this->_isAbstractMethodInParents($name) ||
+				$this->_isStaticMethod($name)) {
+			return $this->_getFullSignature($name);
+		}
+		return "function $name()";
+	}
+
+	/**
+	 *    For a signature specified in an interface, full
+	 *    details must be replicated to be a valid implementation.
+	 *    @param string $name    Method name.
+	 *    @return string         Method signature up to last
+	 *                           bracket.
+	 *    @access private
+	 */
+	function _getFullSignature($name) {
+		$interface = new ReflectionClass($this->_interface);
+		$method = $interface->getMethod($name);
+		$reference = $method->returnsReference() ? '&' : '';
+		$static = $method->isStatic() ? 'static ' : '';
+		return "{$static}function $reference$name(" .
+				implode(', ', $this->_getParameterSignatures($method)) .
+				")";
+	}
+
+	/**
+	 *    Gets the source code for each parameter.
+	 *    @param ReflectionMethod $method   Method object from
+	 *					                    reflection API
+	 *    @return array                     List of strings, each
+	 *                                      a snippet of code.
+	 *    @access private
+	 */
+	function _getParameterSignatures($method) {
+		$signatures = array();
+		foreach ($method->getParameters() as $parameter) {
+			$signature = '';
+			$type = $parameter->getClass();
+			if (is_null($type) && version_compare(phpversion(), '5.1.0', '>=') && $parameter->isArray()) {
+				$signature .= 'array ';
+			} elseif (!is_null($type)) {
+				$signature .= $type->getName() . ' ';
+			}
+			if ($parameter->isPassedByReference()) {
+				$signature .= '&';
+			}
+			$signature .= '$' . $this->_suppressSpurious($parameter->getName());
+			if ($this->_isOptional($parameter)) {
+				$signature .= ' = null';
+			}
+			$signatures[] = $signature;
+		}
+		return $signatures;
+	}
+
+	/**
+	 *    The SPL library has problems with the
+	 *    Reflection library. In particular, you can
+	 *    get extra characters in parameter names :(.
+	 *    @param string $name    Parameter name.
+	 *    @return string         Cleaner name.
+	 *    @access private
+	 */
+	function _suppressSpurious($name) {
+		return str_replace(array('[', ']', ' '), '', $name);
+	}
+
+	/**
+	 *    Test of a reflection parameter being optional
+	 *    that works with early versions of PHP5.
+	 *    @param reflectionParameter $parameter    Is this optional.
+	 *    @return boolean                          True if optional.
+	 *    @access private
+	 */
+	function _isOptional($parameter) {
+		if (method_exists($parameter, 'isOptional')) {
+			return $parameter->isOptional();
+		}
+		return false;
+	}
+}
+?>

Modified: 3.x/trunk/limb/tests_runner/lib/simpletest/test_case.php
===================================================================
--- 3.x/trunk/limb/tests_runner/lib/simpletest/test_case.php	2007-09-02 19:00:06 UTC (rev 6256)
+++ 3.x/trunk/limb/tests_runner/lib/simpletest/test_case.php	2007-09-03 10:41:32 UTC (rev 6257)
@@ -1,671 +1,670 @@
-<?php
-    /**
-     *	Base include file for SimpleTest
-     *	@package	SimpleTest
-     *	@subpackage	UnitTester
-     *	@version	$Id$
-     */
-
-    /**#@+
-     * Includes SimpleTest files and defined the root constant
-     * for dependent libraries.
-     */
-    require_once(dirname(__FILE__) . '/invoker.php');
-    require_once(dirname(__FILE__) . '/errors.php');
-    require_once(dirname(__FILE__) . '/compatibility.php');
-    require_once(dirname(__FILE__) . '/scorer.php');
-    require_once(dirname(__FILE__) . '/expectation.php');
-    require_once(dirname(__FILE__) . '/dumper.php');
-    require_once(dirname(__FILE__) . '/simpletest.php');
-    if (version_compare(phpversion(), '5') >= 0) {
-        require_once(dirname(__FILE__) . '/exceptions.php');
-        require_once(dirname(__FILE__) . '/reflection_php5.php');
-    } else {
-        require_once(dirname(__FILE__) . '/reflection_php4.php');
-    }
-    if (! defined('SIMPLE_TEST')) {
-        /**
-         * @ignore
-         */
-        define('SIMPLE_TEST', dirname(__FILE__) . DIRECTORY_SEPARATOR);
-    }
-    /**#@-*/
-
-    /**
-     *    Basic test case. This is the smallest unit of a test
-     *    suite. It searches for
-     *    all methods that start with the the string "test" and
-     *    runs them. Working test cases extend this class.
-	 *    @package		SimpleTest
-	 *    @subpackage	UnitTester
-     */
-    class SimpleTestCase {
-        var $_label = false;
-        var $_reporter;
-        var $_observers;
-		var $_should_skip = false;
-
-        /**
-         *    Sets up the test with no display.
-         *    @param string $label    If no test name is given then
-         *                            the class name is used.
-         *    @access public
-         */
-        function SimpleTestCase($label = false) {
-            if ($label) {
-                $this->_label = $label;
-            }
-        }
-
-        /**
-         *    Accessor for the test name for subclasses.
-         *    @return string           Name of the test.
-         *    @access public
-         */
-        function getLabel() {
-            return $this->_label ? $this->_label : get_class($this);
-        }
-
-        /**
-         *    This is a placeholder for skipping tests. In this
-         *    method you place skipIf() and skipUnless() calls to
-         *    set the skipping state.
-         *    @access public
-         */
-        function skip() {
-        }
-
-        /**
-         *    Will issue a message to the reporter and tell the test
-         *    case to skip if the incoming flag is true.
-         *    @param string $should_skip    Condition causing the tests to be skipped.
-         *    @param string $message    	Text of skip condition.
-         *    @access public
-         */
-        function skipIf($should_skip, $message = '%s') {
-			if ($should_skip && ! $this->_should_skip) {
-				$this->_should_skip = true;
-				$message = sprintf($message, 'Skipping [' . get_class($this) . ']');
-				$this->_reporter->paintSkip($message . $this->getAssertionLine());
-			}
-        }
-
-        /**
-         *    Will issue a message to the reporter and tell the test
-         *    case to skip if the incoming flag is false.
-         *    @param string $shouldnt_skip  Condition causing the tests to be run.
-         *    @param string $message    	Text of skip condition.
-         *    @access public
-         */
-        function skipUnless($shouldnt_skip, $message = false) {
-			$this->skipIf(! $shouldnt_skip, $message);
-        }
-
-        /**
-         *    Used to invoke the single tests.
-         *    @return SimpleInvoker        Individual test runner.
-         *    @access public
-         */
-        function &createInvoker() {
-            $invoker = &new SimpleErrorTrappingInvoker(new SimpleInvoker($this));
-            if (version_compare(phpversion(), '5') >= 0) {
-                $invoker = &new SimpleExceptionTrappingInvoker($invoker);
-            }
-            return $invoker;
-        }
-
-        /**
-         *    Uses reflection to run every method within itself
-         *    starting with the string "test" unless a method
-         *    is specified.
-         *    @param SimpleReporter $reporter    Current test reporter.
-         *    @return boolean                    True if all tests passed.
-         *    @access public
-         */
-        function run(&$reporter) {
-			$context = &SimpleTest::getContext();
-			$context->setTest($this);
-			$context->setReporter($reporter);
-            $this->_reporter = &$reporter;
-            $started = false;
-            foreach ($this->getTests() as $method) {
-                if ($reporter->shouldInvoke($this->getLabel(), $method)) {
-                    $this->skip();
-                    if ($this->_should_skip) {
-                        break;
-                    }
-                    if (! $started) {
-                        $reporter->paintCaseStart($this->getLabel());
-                        $started = true;
-                    }
-                    $invoker = &$this->_reporter->createInvoker($this->createInvoker());
-                    $invoker->before($method);
-                    $invoker->invoke($method);
-                    $invoker->after($method);
-                }
-            }
-            if ($started) {
-                $reporter->paintCaseEnd($this->getLabel());
-            }
-            unset($this->_reporter);
-            return $reporter->getStatus();
-        }
-
-        /**
-         *    Gets a list of test names. Normally that will
-         *    be all internal methods that start with the
-         *    name "test". This method should be overridden
-         *    if you want a different rule.
-         *    @return array        List of test names.
-         *    @access public
-         */
-        function getTests() {
-            $methods = array();
-            foreach (get_class_methods(get_class($this)) as $method) {
-                if ($this->_isTest($method)) {
-                    $methods[] = $method;
-                }
-            }
-            return $methods;
-        }
-
-        /**
-         *    Tests to see if the method is a test that should
-         *    be run. Currently any method that starts with 'test'
-         *    is a candidate unless it is the constructor.
-         *    @param string $method        Method name to try.
-         *    @return boolean              True if test method.
-         *    @access protected
-         */
-        function _isTest($method) {
-            if (strtolower(substr($method, 0, 4)) == 'test') {
-                return ! SimpleTestCompatibility::isA($this, strtolower($method));
-            }
-            return false;
-        }
-
-        /**
-         *    Announces the start of the test.
-         *    @param string $method    Test method just started.
-         *    @access public
-         */
-        function before($method) {
-            $this->_reporter->paintMethodStart($method);
-            $this->_observers = array();
-        }
-
-        /**
-         *    Sets up unit test wide variables at the start
-         *    of each test method. To be overridden in
-         *    actual user test cases.
-         *    @access public
-         */
-        function setUp() {
-        }
-
-        /**
-         *    Clears the data set in the setUp() method call.
-         *    To be overridden by the user in actual user test cases.
-         *    @access public
-         */
-        function tearDown() {
-        }
-
-        /**
-         *    Announces the end of the test. Includes private clean up.
-         *    @param string $method    Test method just finished.
-         *    @access public
-         */
-        function after($method) {
-            for ($i = 0; $i < count($this->_observers); $i++) {
-                $this->_observers[$i]->atTestEnd($method, $this);
-            }
-            $this->_reporter->paintMethodEnd($method);
-        }
-
-        /**
-         *    Sets up an observer for the test end.
-         *    @param object $observer    Must have atTestEnd()
-         *                               method.
-         *    @access public
-         */
-        function tell(&$observer) {
-            $this->_observers[] = &$observer;
-        }
-
-        /**
-         *    @deprecated
-         */
-        function pass($message = "Pass") {
-            if (! isset($this->_reporter)) {
-                trigger_error('Can only make assertions within test methods');
-            }
-            $this->_reporter->paintPass(
-                    $message . $this->getAssertionLine());
-            return true;
-        }
-
-        /**
-         *    Sends a fail event with a message.
-         *    @param string $message        Message to send.
-         *    @access public
-         */
-        function fail($message = "Fail") {
-            if (! isset($this->_reporter)) {
-                trigger_error('Can only make assertions within test methods');
-            }
-            $this->_reporter->paintFail(
-                    $message . $this->getAssertionLine());
-            return false;
-        }
-
-        /**
-         *    Formats a PHP error and dispatches it to the
-         *    reporter.
-         *    @param integer $severity  PHP error code.
-         *    @param string $message    Text of error.
-         *    @param string $file       File error occoured in.
-         *    @param integer $line      Line number of error.
-         *    @access public
-         */
-        function error($severity, $message, $file, $line) {
-            if (! isset($this->_reporter)) {
-                trigger_error('Can only make assertions within test methods');
-            }
-            $this->_reporter->paintError(
-                    "Unexpected PHP error [$message] severity [$severity] in [$file line $line]");
-        }
-
-        /**
-         *    Formats an exception and dispatches it to the
-         *    reporter.
-         *    @param Exception $exception    Object thrown.
-         *    @access public
-         */
-        function exception($exception) {
-            $this->_reporter->paintException($exception);
-        }
-
-        /**
-         *    @deprecated
-         */
-        function signal($type, &$payload) {
-            if (! isset($this->_reporter)) {
-                trigger_error('Can only make assertions within test methods');
-            }
-            $this->_reporter->paintSignal($type, $payload);
-        }
-
-        /**
-         *    Runs an expectation directly, for extending the
-         *    tests with new expectation classes.
-         *    @param SimpleExpectation $expectation  Expectation subclass.
-         *    @param mixed $compare               Value to compare.
-         *    @param string $message                 Message to display.
-         *    @return boolean                        True on pass
-         *    @access public
-         */
-        function assert(&$expectation, $compare, $message = '%s') {
-            if ($expectation->test($compare)) {
-                return $this->pass(sprintf(
-                        $message,
-                        $expectation->overlayMessage($compare, $this->_reporter->getDumper())));
-            } else {
-                return $this->fail(sprintf(
-                        $message,
-                        $expectation->overlayMessage($compare, $this->_reporter->getDumper())));
-            }
-        }
-
-        /**
-         *	  @deprecated
-         */
-        function assertExpectation(&$expectation, $compare, $message = '%s') {
-        	return $this->assert($expectation, $compare, $message);
-        }
-
-        /**
-         *    Uses a stack trace to find the line of an assertion.
-         *    @return string           Line number of first assert*
-         *                             method embedded in format string.
-         *    @access public
-         */
-        function getAssertionLine() {
-            $trace = new SimpleStackTrace(array('assert', 'expect', 'pass', 'fail', 'skip'));
-            return $trace->traceMethod();
-        }
-
-        /**
-         *    Sends a formatted dump of a variable to the
-         *    test suite for those emergency debugging
-         *    situations.
-         *    @param mixed $variable    Variable to display.
-         *    @param string $message    Message to display.
-         *    @return mixed             The original variable.
-         *    @access public
-         */
-        function dump($variable, $message = false) {
-            $dumper = $this->_reporter->getDumper();
-            $formatted = $dumper->dump($variable);
-            if ($message) {
-                $formatted = $message . "\n" . $formatted;
-            }
-            $this->_reporter->paintFormattedMessage($formatted);
-            return $variable;
-        }
-
-        /**
-         *    @deprecated
-         */
-        function sendMessage($message) {
-            $this->_reporter->PaintMessage($message);
-        }
-
-        /**
-         *    Accessor for the number of subtests.
-         *    @return integer           Number of test cases.
-         *    @access public
-         *    @static
-         */
-        function getSize() {
-            return 1;
-        }
-    }
-
-    /**
-     *  Helps to extract test cases automatically from a file.
-     */
-    class SimpleFileLoader {
-
-        /**
-         *    Builds a test suite from a library of test cases.
-         *    The new suite is composed into this one.
-         *    @param string $test_file        File name of library with
-         *                                    test case classes.
-         *    @return TestSuite               The new test suite.
-         *    @access public
-         */
-        function &load($test_file) {
-            $existing_classes = get_declared_classes();
-            include_once($test_file);
-            $classes = $this->selectRunnableTests(
-                    array_diff(get_declared_classes(), $existing_classes));
-            $suite = &$this->createSuiteFromClasses($test_file, $classes);
-            return $suite;
-        }
-
-        /**
-         *    Calculates the incoming test cases. Skips abstract
-         *    and ignored classes.
-         *    @param array $candidates   Candidate classes.
-         *    @return array              New classes which are test
-         *                               cases that shouldn't be ignored.
-         *    @access public
-         */
-        function selectRunnableTests($candidates) {
-            $classes = array();
-            foreach ($candidates as $class) {
-                if (TestSuite::getBaseTestCase($class)) {
-                    $reflection = new SimpleReflection($class);
-                    if ($reflection->isAbstract()) {
-                        SimpleTest::ignore($class);
-                    }
-                    else {
-                      $classes[] = $class;
-                    }
-                }
-            }
-            return $classes;
-        }
-
-        /**
-         *    Builds a test suite from a class list.
-         *    @param string $title       Title of new group.
-         *    @param array $classes      Test classes.
-         *    @return TestSuite          Group loaded with the new
-         *                               test cases.
-         *    @access public
-         */
-        function &createSuiteFromClasses($title, $classes) {
-            if (count($classes) == 0) {
-                $suite = &new BadTestSuite($title, "No runnable test cases in [$title]");
-                return $suite;
-            }
-            SimpleTest::ignoreParentsIfIgnored($classes);
-            $suite = &new TestSuite($title);
-            foreach ($classes as $class) {
-                if (! SimpleTest::isIgnored($class)) {
-                    $suite->addTestClass($class);
-                }
-            }
-            return $suite;
-        }
-    }
-
-    /**
-     *    This is a composite test class for combining
-     *    test cases and other RunnableTest classes into
-     *    a group test.
-	 *    @package		SimpleTest
-	 *    @subpackage	UnitTester
-     */
-    class TestSuite {
-        var $_label;
-        var $_test_cases;
-
-        /**
-         *    Sets the name of the test suite.
-         *    @param string $label    Name sent at the start and end
-         *                            of the test.
-         *    @access public
-         */
-        function TestSuite($label = false) {
-            $this->_label = $label;
-            $this->_test_cases = array();
-        }
-
-        /**
-         *    Accessor for the test name for subclasses. If the suite
-		 *    wraps a single test case the label defaults to the name of that test.
-         *    @return string           Name of the test.
-         *    @access public
-         */
-        function getLabel() {
-			if (! $this->_label) {
-				return ($this->getSize() == 1) ?
-                        get_class($this->_test_cases[0]) : get_class($this);
-			} else {
-				return $this->_label;
-			}
-        }
-
-        /**
-         *    @deprecated
-         */
-        function addTestCase(&$test_case) {
-            $this->_test_cases[] = &$test_case;
-        }
-
-        /**
-         *    @deprecated
-         */
-        function addTestClass($class) {
-            if (TestSuite::getBaseTestCase($class) == 'testsuite') {
-                $this->_test_cases[] = &new $class();
-            } else {
-                $this->_test_cases[] = $class;
-            }
-        }
-
-        /**
-         *    Adds a test into the suite by instance or class. The class will
-         *    be instantiated if it's a test suite.
-         *    @param SimpleTestCase $test_case  Suite or individual test
-         *                                      case implementing the
-         *                                      runnable test interface.
-         *    @access public
-         */
-        function add(&$test_case) {
-            if (! is_string($test_case)) {
-                $this->_test_cases[] = &$test_case;
-            } elseif (TestSuite::getBaseTestCase($class) == 'testsuite') {
-                $this->_test_cases[] = &new $class();
-            } else {
-                $this->_test_cases[] = $class;
-            }
-        }
-
-        /**
-         *    @deprecated
-         */
-        function addTestFile($test_file) {
-            $this->addFile($test_file);
-        }
-
-        /**
-         *    Builds a test suite from a library of test cases.
-         *    The new suite is composed into this one.
-         *    @param string $test_file        File name of library with
-         *                                    test case classes.
-         *    @access public
-         */
-        function addFile($test_file) {
-            $extractor = new SimpleFileLoader();
-            $this->add($extractor->load($test_file));
-        }
-
-        /**
-         *    Delegates to a visiting collector to add test
-         *    files.
-         *    @param string $path                  Path to scan from.
-         *    @param SimpleCollector $collector    Directory scanner.
-         *    @access public
-         */
-        function collect($path, &$collector) {
-            $collector->collect($this, $path);
-        }
-
-        /**
-         *    Invokes run() on all of the held test cases, instantiating
-         *    them if necessary.
-         *    @param SimpleReporter $reporter    Current test reporter.
-         *    @access public
-         */
-        function run(&$reporter) {
-            $reporter->paintGroupStart($this->getLabel(), $this->getSize());
-            for ($i = 0, $count = count($this->_test_cases); $i < $count; $i++) {
-                if (is_string($this->_test_cases[$i])) {
-                    $class = $this->_test_cases[$i];
-                    $test = &new $class();
-                    $test->run($reporter);
-                    unset($test);
-                } else {
-                    $this->_test_cases[$i]->run($reporter);
-                }
-            }
-            $reporter->paintGroupEnd($this->getLabel());
-            return $reporter->getStatus();
-        }
-
-        /**
-         *    Number of contained test cases.
-         *    @return integer     Total count of cases in the group.
-         *    @access public
-         */
-        function getSize() {
-            $count = 0;
-            foreach ($this->_test_cases as $case) {
-                if (is_string($case)) {
-                    $count++;
-                } else {
-                    $count += $case->getSize();
-                }
-            }
-            return $count;
-        }
-
-        /**
-         *    Test to see if a class is derived from the
-         *    SimpleTestCase class.
-         *    @param string $class     Class name.
-         *    @access public
-         *    @static
-         */
-        function getBaseTestCase($class) {
-            while ($class = get_parent_class($class)) {
-                $class = strtolower($class);
-                if ($class == 'simpletestcase' || $class == 'testsuite') {
-                    return $class;
-                }
-            }
-            return false;
-        }
-    }
-
-    /**
-	 *    @package		SimpleTest
-	 *    @subpackage	UnitTester
-     *    @deprecated
-     */
-    class GroupTest extends TestSuite { }
-
-    /**
-     *    This is a failing group test for when a test suite hasn't
-     *    loaded properly.
-	 *    @package		SimpleTest
-	 *    @subpackage	UnitTester
-     */
-    class BadTestSuite {
-        var $_label;
-        var $_error;
-
-        /**
-         *    Sets the name of the test suite and error message.
-         *    @param string $label    Name sent at the start and end
-         *                            of the test.
-         *    @access public
-         */
-        function BadTestSuite($label, $error) {
-            $this->_label = $label;
-            $this->_error = $error;
-        }
-
-        /**
-         *    Accessor for the test name for subclasses.
-         *    @return string           Name of the test.
-         *    @access public
-         */
-        function getLabel() {
-            return $this->_label;
-        }
-
-        /**
-         *    Sends a single error to the reporter.
-         *    @param SimpleReporter $reporter    Current test reporter.
-         *    @access public
-         */
-        function run(&$reporter) {
-            $reporter->paintGroupStart($this->getLabel(), $this->getSize());
-            $reporter->paintFail('Bad TestSuite [' . $this->getLabel() .
-                    '] with error [' . $this->_error . ']');
-            $reporter->paintGroupEnd($this->getLabel());
-            return $reporter->getStatus();
-        }
-
-        /**
-         *    Number of contained test cases. Always zero.
-         *    @return integer     Total count of cases in the group.
-         *    @access public
-         */
-        function getSize() {
-            return 0;
-        }
-    }
-
-    /**
-	 *    @package		SimpleTest
-	 *    @subpackage	UnitTester
-     *    @deprecated
-     */
-    class BadGroupTest extends BadTestSuite { }
-?>
+<?php
+    /**
+     *	Base include file for SimpleTest
+     *	@package	SimpleTest
+     *	@subpackage	UnitTester
+     *	@version	$Id$
+     */
+
+    /**#@+
+     * Includes SimpleTest files and defined the root constant
+     * for dependent libraries.
+     */
+    require_once(dirname(__FILE__) . '/invoker.php');
+    require_once(dirname(__FILE__) . '/errors.php');
+    require_once(dirname(__FILE__) . '/compatibility.php');
+    require_once(dirname(__FILE__) . '/scorer.php');
+    require_once(dirname(__FILE__) . '/expectation.php');
+    require_once(dirname(__FILE__) . '/dumper.php');
+    require_once(dirname(__FILE__) . '/simpletest.php');
+    if (version_compare(phpversion(), '5') >= 0) {
+        require_once(dirname(__FILE__) . '/exceptions.php');
+        require_once(dirname(__FILE__) . '/reflection_php5.php');
+    } else {
+        require_once(dirname(__FILE__) . '/reflection_php4.php');
+    }
+    if (! defined('SIMPLE_TEST')) {
+        /**
+         * @ignore
+         */
+        define('SIMPLE_TEST', dirname(__FILE__) . DIRECTORY_SEPARATOR);
+    }
+    /**#@-*/
+
+    /**
+     *    Basic test case. This is the smallest unit of a test
+     *    suite. It searches for
+     *    all methods that start with the the string "test" and
+     *    runs them. Working test cases extend this class.
+	 *    @package		SimpleTest
+	 *    @subpackage	UnitTester
+     */
+    class SimpleTestCase {
+        var $_label = false;
+        var $_reporter;
+        var $_observers;
+		var $_should_skip = false;
+
+        /**
+         *    Sets up the test with no display.
+         *    @param string $label    If no test name is given then
+         *                            the class name is used.
+         *    @access public
+         */
+        function SimpleTestCase($label = false) {
+            if ($label) {
+                $this->_label = $label;
+            }
+        }
+
+        /**
+         *    Accessor for the test name for subclasses.
+         *    @return string           Name of the test.
+         *    @access public
+         */
+        function getLabel() {
+            return $this->_label ? $this->_label : get_class($this);
+        }
+
+        /**
+         *    This is a placeholder for skipping tests. In this
+         *    method you place skipIf() and skipUnless() calls to
+         *    set the skipping state.
+         *    @access public
+         */
+        function skip() {
+        }
+
+        /**
+         *    Will issue a message to the reporter and tell the test
+         *    case to skip if the incoming flag is true.
+         *    @param string $should_skip    Condition causing the tests to be skipped.
+         *    @param string $message    	Text of skip condition.
+         *    @access public
+         */
+        function skipIf($should_skip, $message = '%s') {
+			if ($should_skip && ! $this->_should_skip) {
+				$this->_should_skip = true;
+				$message = sprintf($message, 'Skipping [' . get_class($this) . ']');
+				$this->_reporter->paintSkip($message . $this->getAssertionLine());
+			}
+        }
+
+        /**
+         *    Will issue a message to the reporter and tell the test
+         *    case to skip if the incoming flag is false.
+         *    @param string $shouldnt_skip  Condition causing the tests to be run.
+         *    @param string $message    	Text of skip condition.
+         *    @access public
+         */
+        function skipUnless($shouldnt_skip, $message = false) {
+			$this->skipIf(! $shouldnt_skip, $message);
+        }
+
+        /**
+         *    Used to invoke the single tests.
+         *    @return SimpleInvoker        Individual test runner.
+         *    @access public
+         */
+        function &createInvoker() {
+            $invoker = &new SimpleErrorTrappingInvoker(new SimpleInvoker($this));
+            if (version_compare(phpversion(), '5') >= 0) {
+                $invoker = &new SimpleExceptionTrappingInvoker($invoker);
+            }
+            return $invoker;
+        }
+
+        /**
+         *    Uses reflection to run every method within itself
+         *    starting with the string "test" unless a method
+         *    is specified.
+         *    @param SimpleReporter $reporter    Current test reporter.
+         *    @return boolean                    True if all tests passed.
+         *    @access public
+         */
+        function run(&$reporter) {
+			$context = &SimpleTest::getContext();
+			$context->setTest($this);
+			$context->setReporter($reporter);
+            $this->_reporter = &$reporter;
+            $started = false;
+            foreach ($this->getTests() as $method) {
+                if ($reporter->shouldInvoke($this->getLabel(), $method)) {
+                    $this->skip();
+                    if ($this->_should_skip) {
+                        break;
+                    }
+                    if (! $started) {
+                        $reporter->paintCaseStart($this->getLabel());
+                        $started = true;
+                    }
+                    $invoker = &$this->_reporter->createInvoker($this->createInvoker());
+                    $invoker->before($method);
+                    $invoker->invoke($method);
+                    $invoker->after($method);
+                }
+            }
+            if ($started) {
+                $reporter->paintCaseEnd($this->getLabel());
+            }
+            unset($this->_reporter);
+            return $reporter->getStatus();
+        }
+
+        /**
+         *    Gets a list of test names. Normally that will
+         *    be all internal methods that start with the
+         *    name "test". This method should be overridden
+         *    if you want a different rule.
+         *    @return array        List of test names.
+         *    @access public
+         */
+        function getTests() {
+            $methods = array();
+            foreach (get_class_methods(get_class($this)) as $method) {
+                if ($this->_isTest($method)) {
+                    $methods[] = $method;
+                }
+            }
+            return $methods;
+        }
+
+        /**
+         *    Tests to see if the method is a test that should
+         *    be run. Currently any method that starts with 'test'
+         *    is a candidate unless it is the constructor.
+         *    @param string $method        Method name to try.
+         *    @return boolean              True if test method.
+         *    @access protected
+         */
+        function _isTest($method) {
+            if (strtolower(substr($method, 0, 4)) == 'test') {
+                return ! SimpleTestCompatibility::isA($this, strtolower($method));
+            }
+            return false;
+        }
+
+        /**
+         *    Announces the start of the test.
+         *    @param string $method    Test method just started.
+         *    @access public
+         */
+        function before($method) {
+            $this->_reporter->paintMethodStart($method);
+            $this->_observers = array();
+        }
+
+        /**
+         *    Sets up unit test wide variables at the start
+         *    of each test method. To be overridden in
+         *    actual user test cases.
+         *    @access public
+         */
+        function setUp() {
+        }
+
+        /**
+         *    Clears the data set in the setUp() method call.
+         *    To be overridden by the user in actual user test cases.
+         *    @access public
+         */
+        function tearDown() {
+        }
+
+        /**
+         *    Announces the end of the test. Includes private clean up.
+         *    @param string $method    Test method just finished.
+         *    @access public
+         */
+        function after($method) {
+            for ($i = 0; $i < count($this->_observers); $i++) {
+                $this->_observers[$i]->atTestEnd($method, $this);
+            }
+            $this->_reporter->paintMethodEnd($method);
+        }
+
+        /**
+         *    Sets up an observer for the test end.
+         *    @param object $observer    Must have atTestEnd()
+         *                               method.
+         *    @access public
+         */
+        function tell(&$observer) {
+            $this->_observers[] = &$observer;
+        }
+
+        /**
+         *    @deprecated
+         */
+        function pass($message = "Pass") {
+            if (! isset($this->_reporter)) {
+                trigger_error('Can only make assertions within test methods');
+            }
+            $this->_reporter->paintPass(
+                    $message . $this->getAssertionLine());
+            return true;
+        }
+
+        /**
+         *    Sends a fail event with a message.
+         *    @param string $message        Message to send.
+         *    @access public
+         */
+        function fail($message = "Fail") {
+            if (! isset($this->_reporter)) {
+                trigger_error('Can only make assertions within test methods');
+            }
+            $this->_reporter->paintFail(
+                    $message . $this->getAssertionLine());
+            return false;
+        }
+
+        /**
+         *    Formats a PHP error and dispatches it to the
+         *    reporter.
+         *    @param integer $severity  PHP error code.
+         *    @param string $message    Text of error.
+         *    @param string $file       File error occoured in.
+         *    @param integer $line      Line number of error.
+         *    @access public
+         */
+        function error($severity, $message, $file, $line) {
+            if (! isset($this->_reporter)) {
+                trigger_error('Can only make assertions within test methods');
+            }
+            $this->_reporter->paintError(
+                    "Unexpected PHP error [$message] severity [$severity] in [$file line $line]");
+        }
+
+        /**
+         *    Formats an exception and dispatches it to the
+         *    reporter.
+         *    @param Exception $exception    Object thrown.
+         *    @access public
+         */
+        function exception($exception) {
+            $this->_reporter->paintException($exception);
+        }
+
+        /**
+         *    @deprecated
+         */
+        function signal($type, &$payload) {
+            if (! isset($this->_reporter)) {
+                trigger_error('Can only make assertions within test methods');
+            }
+            $this->_reporter->paintSignal($type, $payload);
+        }
+
+        /**
+         *    Runs an expectation directly, for extending the
+         *    tests with new expectation classes.
+         *    @param SimpleExpectation $expectation  Expectation subclass.
+         *    @param mixed $compare               Value to compare.
+         *    @param string $message                 Message to display.
+         *    @return boolean                        True on pass
+         *    @access public
+         */
+        function assert(&$expectation, $compare, $message = '%s') {
+            if ($expectation->test($compare)) {
+                return $this->pass(sprintf(
+                        $message,
+                        $expectation->overlayMessage($compare, $this->_reporter->getDumper())));
+            } else {
+                return $this->fail(sprintf(
+                        $message,
+                        $expectation->overlayMessage($compare, $this->_reporter->getDumper())));
+            }
+        }
+
+        /**
+         *	  @deprecated
+         */
+        function assertExpectation(&$expectation, $compare, $message = '%s') {
+        	return $this->assert($expectation, $compare, $message);
+        }
+
+        /**
+         *    Uses a stack trace to find the line of an assertion.
+         *    @return string           Line number of first assert*
+         *                             method embedded in format string.
+         *    @access public
+         */
+        function getAssertionLine() {
+            $trace = new SimpleStackTrace(array('assert', 'expect', 'pass', 'fail', 'skip'));
+            return $trace->traceMethod();
+        }
+
+        /**
+         *    Sends a formatted dump of a variable to the
+         *    test suite for those emergency debugging
+         *    situations.
+         *    @param mixed $variable    Variable to display.
+         *    @param string $message    Message to display.
+         *    @return mixed             The original variable.
+         *    @access public
+         */
+        function dump($variable, $message = false) {
+            $dumper = $this->_reporter->getDumper();
+            $formatted = $dumper->dump($variable);
+            if ($message) {
+                $formatted = $message . "\n" . $formatted;
+            }
+            $this->_reporter->paintFormattedMessage($formatted);
+            return $variable;
+        }
+
+        /**
+         *    @deprecated
+         */
+        function sendMessage($message) {
+            $this->_reporter->PaintMessage($message);
+        }
+
+        /**
+         *    Accessor for the number of subtests.
+         *    @return integer           Number of test cases.
+         *    @access public
+         *    @static
+         */
+        function getSize() {
+            return 1;
+        }
+    }
+
+    /**
+     *  Helps to extract test cases automatically from a file.
+     */
+    class SimpleFileLoader {
+
+        /**
+         *    Builds a test suite from a library of test cases.
+         *    The new suite is composed into this one.
+         *    @param string $test_file        File name of library with
+         *                                    test case classes.
+         *    @return TestSuite               The new test suite.
+         *    @access public
+         */
+        function &load($test_file) {
+            $existing_classes = get_declared_classes();
+            include_once($test_file);
+            $classes = $this->selectRunnableTests(
+                    array_diff(get_declared_classes(), $existing_classes));
+            $suite = &$this->createSuiteFromClasses($test_file, $classes);
+            return $suite;
+        }
+
+        /**
+         *    Calculates the incoming test cases. Skips abstract
+         *    and ignored classes.
+         *    @param array $candidates   Candidate classes.
+         *    @return array              New classes which are test
+         *                               cases that shouldn't be ignored.
+         *    @access public
+         */
+        function selectRunnableTests($candidates) {
+            $classes = array();
+            foreach ($candidates as $class) {
+                if (TestSuite::getBaseTestCase($class)) {
+                    $reflection = new SimpleReflection($class);
+                    if ($reflection->isAbstract()) {
+                        SimpleTest::ignore($class);
+                    } else {
+                        $classes[] = $class;
+                    }
+                }
+            }
+            return $classes;
+        }
+
+        /**
+         *    Builds a test suite from a class list.
+         *    @param string $title       Title of new group.
+         *    @param array $classes      Test classes.
+         *    @return TestSuite          Group loaded with the new
+         *                               test cases.
+         *    @access public
+         */
+        function &createSuiteFromClasses($title, $classes) {
+            if (count($classes) == 0) {
+                $suite = &new BadTestSuite($title, "No runnable test cases in [$title]");
+                return $suite;
+            }
+            SimpleTest::ignoreParentsIfIgnored($classes);
+            $suite = &new TestSuite($title);
+            foreach ($classes as $class) {
+                if (! SimpleTest::isIgnored($class)) {
+                    $suite->addTestClass($class);
+                }
+            }
+            return $suite;
+        }
+    }
+
+    /**
+     *    This is a composite test class for combining
+     *    test cases and other RunnableTest classes into
+     *    a group test.
+	 *    @package		SimpleTest
+	 *    @subpackage	UnitTester
+     */
+    class TestSuite {
+        var $_label;
+        var $_test_cases;
+
+        /**
+         *    Sets the name of the test suite.
+         *    @param string $label    Name sent at the start and end
+         *                            of the test.
+         *    @access public
+         */
+        function TestSuite($label = false) {
+            $this->_label = $label;
+            $this->_test_cases = array();
+        }
+
+        /**
+         *    Accessor for the test name for subclasses. If the suite
+		 *    wraps a single test case the label defaults to the name of that test.
+         *    @return string           Name of the test.
+         *    @access public
+         */
+        function getLabel() {
+			if (! $this->_label) {
+				return ($this->getSize() == 1) ?
+                        get_class($this->_test_cases[0]) : get_class($this);
+			} else {
+				return $this->_label;
+			}
+        }
+
+        /**
+         *    @deprecated
+         */
+        function addTestCase(&$test_case) {
+            $this->_test_cases[] = &$test_case;
+        }
+
+        /**
+         *    @deprecated
+         */
+        function addTestClass($class) {
+            if (TestSuite::getBaseTestCase($class) == 'testsuite') {
+                $this->_test_cases[] = &new $class();
+            } else {
+                $this->_test_cases[] = $class;
+            }
+        }
+
+        /**
+         *    Adds a test into the suite by instance or class. The class will
+         *    be instantiated if it's a test suite.
+         *    @param SimpleTestCase $test_case  Suite or individual test
+         *                                      case implementing the
+         *                                      runnable test interface.
+         *    @access public
+         */
+        function add(&$test_case) {
+            if (! is_string($test_case)) {
+                $this->_test_cases[] = &$test_case;
+            } elseif (TestSuite::getBaseTestCase($class) == 'testsuite') {
+                $this->_test_cases[] = &new $class();
+            } else {
+                $this->_test_cases[] = $class;
+            }
+        }
+
+        /**
+         *    @deprecated
+         */
+        function addTestFile($test_file) {
+            $this->addFile($test_file);
+        }
+
+        /**
+         *    Builds a test suite from a library of test cases.
+         *    The new suite is composed into this one.
+         *    @param string $test_file        File name of library with
+         *                                    test case classes.
+         *    @access public
+         */
+        function addFile($test_file) {
+            $extractor = new SimpleFileLoader();
+            $this->add($extractor->load($test_file));
+        }
+
+        /**
+         *    Delegates to a visiting collector to add test
+         *    files.
+         *    @param string $path                  Path to scan from.
+         *    @param SimpleCollector $collector    Directory scanner.
+         *    @access public
+         */
+        function collect($path, &$collector) {
+            $collector->collect($this, $path);
+        }
+
+        /**
+         *    Invokes run() on all of the held test cases, instantiating
+         *    them if necessary.
+         *    @param SimpleReporter $reporter    Current test reporter.
+         *    @access public
+         */
+        function run(&$reporter) {
+            $reporter->paintGroupStart($this->getLabel(), $this->getSize());
+            for ($i = 0, $count = count($this->_test_cases); $i < $count; $i++) {
+                if (is_string($this->_test_cases[$i])) {
+                    $class = $this->_test_cases[$i];
+                    $test = &new $class();
+                    $test->run($reporter);
+                    unset($test);
+                } else {
+                    $this->_test_cases[$i]->run($reporter);
+                }
+            }
+            $reporter->paintGroupEnd($this->getLabel());
+            return $reporter->getStatus();
+        }
+
+        /**
+         *    Number of contained test cases.
+         *    @return integer     Total count of cases in the group.
+         *    @access public
+         */
+        function getSize() {
+            $count = 0;
+            foreach ($this->_test_cases as $case) {
+                if (is_string($case)) {
+                    $count++;
+                } else {
+                    $count += $case->getSize();
+                }
+            }
+            return $count;
+        }
+
+        /**
+         *    Test to see if a class is derived from the
+         *    SimpleTestCase class.
+         *    @param string $class     Class name.
+         *    @access public
+         *    @static
+         */
+        function getBaseTestCase($class) {
+            while ($class = get_parent_class($class)) {
+                $class = strtolower($class);
+                if ($class == 'simpletestcase' || $class == 'testsuite') {
+                    return $class;
+                }
+            }
+            return false;
+        }
+    }
+
+    /**
+	 *    @package		SimpleTest
+	 *    @subpackage	UnitTester
+     *    @deprecated
+     */
+    class GroupTest extends TestSuite { }
+
+    /**
+     *    This is a failing group test for when a test suite hasn't
+     *    loaded properly.
+	 *    @package		SimpleTest
+	 *    @subpackage	UnitTester
+     */
+    class BadTestSuite {
+        var $_label;
+        var $_error;
+
+        /**
+         *    Sets the name of the test suite and error message.
+         *    @param string $label    Name sent at the start and end
+         *                            of the test.
+         *    @access public
+         */
+        function BadTestSuite($label, $error) {
+            $this->_label = $label;
+            $this->_error = $error;
+        }
+
+        /**
+         *    Accessor for the test name for subclasses.
+         *    @return string           Name of the test.
+         *    @access public
+         */
+        function getLabel() {
+            return $this->_label;
+        }
+
+        /**
+         *    Sends a single error to the reporter.
+         *    @param SimpleReporter $reporter    Current test reporter.
+         *    @access public
+         */
+        function run(&$reporter) {
+            $reporter->paintGroupStart($this->getLabel(), $this->getSize());
+            $reporter->paintFail('Bad TestSuite [' . $this->getLabel() .
+                    '] with error [' . $this->_error . ']');
+            $reporter->paintGroupEnd($this->getLabel());
+            return $reporter->getStatus();
+        }
+
+        /**
+         *    Number of contained test cases. Always zero.
+         *    @return integer     Total count of cases in the group.
+         *    @access public
+         */
+        function getSize() {
+            return 0;
+        }
+    }
+
+    /**
+	 *    @package		SimpleTest
+	 *    @subpackage	UnitTester
+     *    @deprecated
+     */
+    class BadGroupTest extends BadTestSuite { }
+?>



More information about the limb-svn mailing list