diff options
Diffstat (limited to 'tests/test_tools/simpletest/xml.php')
| -rw-r--r-- | tests/test_tools/simpletest/xml.php | 615 | 
1 files changed, 615 insertions, 0 deletions
diff --git a/tests/test_tools/simpletest/xml.php b/tests/test_tools/simpletest/xml.php new file mode 100644 index 00000000..dd007d41 --- /dev/null +++ b/tests/test_tools/simpletest/xml.php @@ -0,0 +1,615 @@ +<?php +    /** +     *	base include file for SimpleTest +     *	@package	SimpleTest +     *	@subpackage	UnitTester +     *	@version	$Id: xml.php,v 1.20 2004/08/04 22:09:39 lastcraft Exp $ +     */ + +    /**#@+ +     *	include other SimpleTest class files +     */ +    require_once(dirname(__FILE__) . '/scorer.php'); +    /**#@-*/ +    +    /** +     *    Creates the XML needed for remote communication +     *    by SimpleTest. +	 *	  @package SimpleTest +	 *	  @subpackage UnitTester +     */ +    class XmlReporter extends SimpleReporter { +        protected $_indent; +        protected $_namespace; +         +        /** +         *    Does nothing yet. +         *    @access public +         */ +        function XmlReporter($namespace = false, $indent = '  ') { +            $this->SimpleReporter(); +            $this->_namespace = ($namespace ? $namespace . ':' : ''); +            $this->_indent = $indent; +        } +         +        /** +         *    Calculates the pretty printing indent level +         *    from the current level of nesting. +         *    @param integer $offset  Extra indenting level. +         *    @return string          Leading space. +         *    @access protected +         */ +        function _getIndent($offset = 0) { +            return str_repeat( +                    $this->_indent, +                    count($this->getTestList()) + $offset); +        } +         +        /** +         *    Converts character string to parsed XML +         *    entities string. +         *    @param string text        Unparsed character data. +         *    @return string            Parsed character data. +         *    @access public +         */ +        function toParsedXml($text) { +            return str_replace( +                    array('&', '<', '>', '"', '\''), +                    array('&', '<', '>', '"', '''), +                    $text); +        } +         +        /** +         *    Paints the start of a group test. +         *    @param string $test_name   Name of test that is starting. +         *    @param integer $size       Number of test cases starting. +         *    @access public +         */ +        function paintGroupStart($test_name, $size) { +            parent::paintGroupStart($test_name, $size); +            print $this->_getIndent(); +            print "<" . $this->_namespace . "group size=\"$size\">\n"; +            print $this->_getIndent(1); +            print "<" . $this->_namespace . "name>" . +                    $this->toParsedXml($test_name) . +                    "</" . $this->_namespace . "name>\n"; +        } +         +        /** +         *    Paints the end of a group test. +         *    @param string $test_name   Name of test that is ending. +         *    @access public +         */ +        function paintGroupEnd($test_name) { +            print $this->_getIndent(); +            print "</" . $this->_namespace . "group>\n"; +            parent::paintGroupEnd($test_name); +        } +         +        /** +         *    Paints the start of a test case. +         *    @param string $test_name   Name of test that is starting. +         *    @access public +         */ +        function paintCaseStart($test_name) { +            parent::paintCaseStart($test_name); +            print $this->_getIndent(); +            print "<" . $this->_namespace . "case>\n"; +            print $this->_getIndent(1); +            print "<" . $this->_namespace . "name>" . +                    $this->toParsedXml($test_name) . +                    "</" . $this->_namespace . "name>\n"; +        } +         +        /** +         *    Paints the end of a test case. +         *    @param string $test_name   Name of test that is ending. +         *    @access public +         */ +        function paintCaseEnd($test_name) { +            print $this->_getIndent(); +            print "</" . $this->_namespace . "case>\n"; +            parent::paintCaseEnd($test_name); +        } +         +        /** +         *    Paints the start of a test method. +         *    @param string $test_name   Name of test that is starting. +         *    @access public +         */ +        function paintMethodStart($test_name) { +            parent::paintMethodStart($test_name); +            print $this->_getIndent(); +            print "<" . $this->_namespace . "test>\n"; +            print $this->_getIndent(1); +            print "<" . $this->_namespace . "name>" . +                    $this->toParsedXml($test_name) . +                    "</" . $this->_namespace . "name>\n"; +        } +         +        /** +         *    Paints the end of a test method. +         *    @param string $test_name   Name of test that is ending. +         *    @param integer $progress   Number of test cases ending. +         *    @access public +         */ +        function paintMethodEnd($test_name) { +            print $this->_getIndent(); +            print "</" . $this->_namespace . "test>\n"; +            parent::paintMethodEnd($test_name); +        } +         +        /** +         *    Increments the pass count. +         *    @param string $message        Message is ignored. +         *    @access public +         */ +        function paintPass($message) { +            parent::paintPass($message); +            print $this->_getIndent(1); +            print "<" . $this->_namespace . "pass>"; +            print $this->toParsedXml($message); +            print "</" . $this->_namespace . "pass>\n"; +        } +         +        /** +         *    Increments the fail count. +         *    @param string $message        Message is ignored. +         *    @access public +         */ +        function paintFail($message) { +            parent::paintFail($message); +            print $this->_getIndent(1); +            print "<" . $this->_namespace . "fail>"; +            print $this->toParsedXml($message); +            print "</" . $this->_namespace . "fail>\n"; +        } +         +        /** +         *    Paints a PHP error or exception. +         *    @param string $message        Message is ignored. +         *    @access public +         *    @abstract +         */ +        function paintException($message) { +            parent::paintException($message); +            print $this->_getIndent(1); +            print "<" . $this->_namespace . "exception>"; +            print $this->toParsedXml($message); +            print "</" . $this->_namespace . "exception>\n"; +        } + +        /** +         *    Paints a simple supplementary message. +         *    @param string $message        Text to display. +         *    @access public +         */ +        function paintMessage($message) { +            parent::paintMessage($message); +            print $this->_getIndent(1); +            print "<" . $this->_namespace . "message>"; +            print $this->toParsedXml($message); +            print "</" . $this->_namespace . "message>\n"; +        } +         +        /** +         *    Paints a formatted ASCII message such as a +         *    variable dump. +         *    @param string $message        Text to display. +         *    @access public +         */ +        function paintFormattedMessage($message) { +            parent::paintFormattedMessage($message); +            print $this->_getIndent(1); +            print "<" . $this->_namespace . "formatted>"; +            print "<![CDATA[$message]]>"; +            print "</" . $this->_namespace . "formatted>\n"; +        } + +        /** +         *    Serialises the event object. +         *    @param string $type        Event type as text. +         *    @param mixed $payload      Message or object. +         *    @access public +         */ +        function paintSignal($type, $payload) { +            parent::paintSignal($type, $payload); +            print $this->_getIndent(1); +            print "<" . $this->_namespace . "signal type=\"$type\">"; +            print "<![CDATA[" . serialize($payload) . "]]>"; +            print "</" . $this->_namespace . "signal>\n"; +        } + +        /** +         *    Paints the test document header. +         *    @param string $test_name     First test top level +         *                                 to start. +         *    @access public +         *    @abstract +         */ +        function paintHeader($test_name) { +            if (! SimpleReporter::inCli()) { +                header('Content-type: text/xml'); +            } +            print "<?xml version=\"1.0\""; +            if ($this->_namespace) { +                print " xmlns:" . $this->_namespace . +                        "=\"www.lastcraft.com/SimpleTest/Beta3/Report\""; +            } +            print "?>\n"; +            print "<" . $this->_namespace . "run>\n"; +        } +         +        /** +         *    Paints the test document footer. +         *    @param string $test_name        The top level test. +         *    @access public +         *    @abstract +         */ +        function paintFooter($test_name) { +            print "</" . $this->_namespace . "run>\n"; +        } +    } +     +    /** +     *    Accumulator for incoming tag. Holds the +     *    incoming test structure information for +     *    later dispatch to the reporter. +	 *	  @package SimpleTest +	 *	  @subpackage UnitTester +     */ +    class NestingXmlTag { +        protected $_name; +        protected $_attributes; +         +        /** +         *    Sets the basic test information except +         *    the name. +         *    @param hash $attributes   Name value pairs. +         *    @access public +         */ +        function NestingXmlTag($attributes) { +            $this->_name = false; +            $this->_attributes = $attributes; +        } +         +        /** +         *    Sets the test case/method name. +         *    @param string $name        Name of test. +         *    @access public +         */ +        function setName($name) { +            $this->_name = $name; +        } +         +        /** +         *    Accessor for name. +         *    @return string        Name of test. +         *    @access public +         */ +        function getName() { +            return $this->_name; +        } +         +        /** +         *    Accessor for attributes. +         *    @return hash        All attributes. +         *    @access protected +         */ +        function _getAttributes() { +            return $this->_attributes; +        } +    } +     +    /** +     *    Accumulator for incoming method tag. Holds the +     *    incoming test structure information for +     *    later dispatch to the reporter. +	 *	  @package SimpleTest +	 *	  @subpackage UnitTester +     */ +    class NestingMethodTag extends NestingXmlTag { +         +        /** +         *    Sets the basic test information except +         *    the name. +         *    @param hash $attributes   Name value pairs. +         *    @access public +         */ +        function NestingMethodTag($attributes) { +            $this->NestingXmlTag($attributes); +        } +         +        /** +         *    Signals the appropriate start event on the +         *    listener. +         *    @param SimpleReporter $listener    Target for events. +         *    @access public +         */ +        function paintStart($listener) { +            $listener->paintMethodStart($this->getName()); +        }     +         +        /** +         *    Signals the appropriate end event on the +         *    listener. +         *    @param SimpleReporter $listener    Target for events. +         *    @access public +         */ +        function paintEnd($listener) { +            $listener->paintMethodEnd($this->getName()); +        } +    } +     +    /** +     *    Accumulator for incoming case tag. Holds the +     *    incoming test structure information for +     *    later dispatch to the reporter. +	 *	  @package SimpleTest +	 *	  @subpackage UnitTester +     */ +    class NestingCaseTag extends NestingXmlTag { +         +        /** +         *    Sets the basic test information except +         *    the name. +         *    @param hash $attributes   Name value pairs. +         *    @access public +         */ +        function NestingCaseTag($attributes) { +            $this->NestingXmlTag($attributes); +        } +         +        /** +         *    Signals the appropriate start event on the +         *    listener. +         *    @param SimpleReporter $listener    Target for events. +         *    @access public +         */ +        function paintStart($listener) { +            $listener->paintCaseStart($this->getName()); +        }     +         +        /** +         *    Signals the appropriate end event on the +         *    listener. +         *    @param SimpleReporter $listener    Target for events. +         *    @access public +         */ +        function paintEnd($listener) { +            $listener->paintCaseEnd($this->getName()); +        } +    } +     +    /** +     *    Accumulator for incoming group tag. Holds the +     *    incoming test structure information for +     *    later dispatch to the reporter. +	 *	  @package SimpleTest +	 *	  @subpackage UnitTester +     */ +    class NestingGroupTag extends NestingXmlTag { +         +        /** +         *    Sets the basic test information except +         *    the name. +         *    @param hash $attributes   Name value pairs. +         *    @access public +         */ +        function NestingGroupTag($attributes) { +            $this->NestingXmlTag($attributes); +        } + +        /** +         *    Signals the appropriate start event on the +         *    listener. +         *    @param SimpleReporter $listener    Target for events. +         *    @access public +         */ +        function paintStart($listener) { +            $listener->paintGroupStart($this->getName(), $this->getSize()); +        } +         +        /** +         *    Signals the appropriate end event on the +         *    listener. +         *    @param SimpleReporter $listener    Target for events. +         *    @access public +         */ +        function paintEnd($listener) { +            $listener->paintGroupEnd($this->getName()); +        } +         +        /** +         *    The size in the attributes. +         *    @return integer     Value of size attribute or zero. +         *    @access public +         */ +        function getSize() { +            $attributes = $this->_getAttributes(); +            if (isset($attributes['SIZE'])) { +                return (integer)$attributes['SIZE']; +            } +            return 0; +        } +    } +     +    /** +     *    Parser for importing the output of the XmlReporter. +     *    Dispatches that output to another reporter. +	 *	  @package SimpleTest +	 *	  @subpackage UnitTester +     */ +    class SimpleTestXmlParser { +        protected $_listener; +        protected $_expat; +        protected $_tag_stack; +        protected $_in_content_tag; +        protected $_content; +        protected $_attributes; +         +        /** +         *    Loads a listener with the SimpleReporter +         *    interface. +         *    @param SimpleReporter $listener   Listener of tag events. +         *    @access public +         */ +        function SimpleTestXmlParser($listener) { +            $this->_listener = $listener; +            $this->_expat = $this->_createParser(); +            $this->_tag_stack = array(); +            $this->_in_content_tag = false; +            $this->_content = ''; +            $this->_attributes = array(); +        } +         +        /** +         *    Parses a block of XML sending the results to +         *    the listener. +         *    @param string $chunk        Block of text to read. +         *    @return boolean             True if valid XML. +         *    @access public +         */ +        function parse($chunk) { +            if (! xml_parse($this->_expat, $chunk)) { +                trigger_error('XML parse error with ' . +                        xml_error_string(xml_get_error_code($this->_expat))); +                return false; +            } +            return true; +        } +         +        /** +         *    Sets up expat as the XML parser. +         *    @return resource        Expat handle. +         *    @access protected +         */ +        function _createParser() { +            $expat = xml_parser_create(); +            xml_set_object($expat, $this); +            xml_set_element_handler($expat, '_startElement', '_endElement'); +            xml_set_character_data_handler($expat, '_addContent'); +            xml_set_default_handler($expat, '_default'); +            return $expat; +        } +         +        /** +         *    Opens a new test nesting level. +         *    @return NestedXmlTag     The group, case or method tag +         *                             to start. +         *    @access private +         */ +        function _pushNestingTag($nested) { +            array_unshift($this->_tag_stack, $nested); +        } +         +        /** +         *    Accessor for current test structure tag. +         *    @return NestedXmlTag     The group, case or method tag +         *                             being parsed. +         *    @access private +         */ +        function _getCurrentNestingTag() { +            return $this->_tag_stack[0]; +        } +         +        /** +         *    Ends a nesting tag. +         *    @return NestedXmlTag     The group, case or method tag +         *                             just finished. +         *    @access private +         */ +        function _popNestingTag() { +            return array_shift($this->_tag_stack); +        } +         +        /** +         *    Test if tag is a leaf node with only text content. +         *    @param string $tag        XML tag name. +         *    @return @boolean          True if leaf, false if nesting. +         *    @private +         */ +        function _isLeaf($tag) { +            return in_array( +                    $tag, +                    array('NAME', 'PASS', 'FAIL', 'EXCEPTION', 'MESSAGE', 'FORMATTED', 'SIGNAL')); +        } + +        /** +         *    Handler for start of event element. +         *    @param resource $expat     Parser handle. +         *    @param string $tag         Element name. +         *    @param hash $attributes    Name value pairs. +         *                               Attributes without content +         *                               are marked as true. +         *    @access protected +         */ +        function _startElement($expat, $tag, $attributes) { +            $this->_attributes = $attributes; +            if ($tag == 'GROUP') { +                $this->_pushNestingTag(new NestingGroupTag($attributes)); +            } elseif ($tag == 'CASE') { +                $this->_pushNestingTag(new NestingCaseTag($attributes)); +            } elseif ($tag == 'TEST') { +                $this->_pushNestingTag(new NestingMethodTag($attributes)); +            } elseif ($this->_isLeaf($tag)) { +                $this->_in_content_tag = true; +                $this->_content = ''; +            } +        } +         +        /** +         *    End of element event. +         *    @param resource $expat     Parser handle. +         *    @param string $tag         Element name. +         *    @access protected +         */ +        function _endElement($expat, $tag) { +            $this->_in_content_tag = false; +            if (in_array($tag, array('GROUP', 'CASE', 'TEST'))) { +                $nesting_tag = $this->_popNestingTag(); +                $nesting_tag->paintEnd($this->_listener); +            } elseif ($tag == 'NAME') { +                $nesting_tag = $this->_getCurrentNestingTag(); +                $nesting_tag->setName($this->_content); +                $nesting_tag->paintStart($this->_listener); +            } elseif ($tag == 'PASS') { +                $this->_listener->paintPass($this->_content); +            } elseif ($tag == 'FAIL') { +                $this->_listener->paintFail($this->_content); +            } elseif ($tag == 'EXCEPTION') { +                $this->_listener->paintException($this->_content); +            } elseif ($tag == 'SIGNAL') { +                $this->_listener->paintSignal( +                        $this->_attributes['TYPE'], +                        unserialize($this->_content)); +            } elseif ($tag == 'MESSAGE') { +                $this->_listener->paintMessage($this->_content); +            } elseif ($tag == 'FORMATTED') { +                $this->_listener->paintFormattedMessage($this->_content); +            } +        } +         +        /** +         *    Content between start and end elements. +         *    @param resource $expat     Parser handle. +         *    @param string $text        Usually output messages. +         *    @access protected +         */ +        function _addContent($expat, $text) { +            if ($this->_in_content_tag) { +                $this->_content .= $text; +            } +            return true; +        } +         +        /** +         *    XML and Doctype handler. Discards all such content. +         *    @param resource $expat     Parser handle. +         *    @param string $default     Text of default content. +         *    @access protected +         */ +        function _default($expat, $default) { +        } +    } +?>  | 
