<?php

/*
Sources of test case material:

http://www.w3.org/XML/Test/
http://www.hixie.ch/tests/adhoc/html/parsing/
http://www.w3.org/MarkUp/SGML/sgml-lex/sgml-lex
*/

Mock::generate('Wact_Html_Sax_Handler', 'MockWact_Html_Sax_Handler');

abstract class WactSaxTestCase extends Wact_Test_Case {

    var $parser;
    var $handler;

    function setUp() {
        $this->handler = new MockWact_Html_Sax_Handler($this);
        
        $this->parser = $this->createParser();
        
        $this->parser->setHandler($this->handler);
    }

    function tearDown() {
        $this->handler->tally();
    }
    
    abstract function createParser();

}

/**
*/
class HtmlContentSaxTestCase extends WactSaxTestCase {

    function createParser() {
        return new Wact_Html_Sax_Parser();
    }
    
    function testEmpty() {
        $this->handler->expectNever('characters');
        $this->handler->expectNever('startElement');
        $this->handler->expectNever('endElement');
        $this->parser->parse('');
    }

    function testSimpledata() {
        $this->handler->expectOnce('characters', array('content'));
        $this->parser->parse('content');
    }

    function testPreservingWhiteSpace() {
        $this->handler->expectOnce('characters', array(" content\t\r\n "));
        $this->parser->parse(" content\t\r\n ");
    }

}

/*
*   These test cases are valid HTML markup
*/
class HtmlSaxReaderElementMarkupTestCase extends WactSaxTestCase {

    function createParser() {
        return new Wact_Html_Sax_Parser();
    }

    function testEmptyElement() {
        $this->handler->expectOnce('startElement', array('tag', array()));
        $this->handler->expectOnce('endElement', array('tag'));
        $this->parser->parse('<tag></tag>');
    }
    
    function testElementWithContent() {
        $this->handler->expectOnce('startElement', array('tag', array()));
        $this->handler->expectOnce('characters', array('content'));
        $this->handler->expectOnce('endElement', array('tag'));
        $this->parser->parse('<tag>content</tag>');
    }

    function testStartElementWithPreContent() {
        $this->handler->expectOnce('characters', array('content'));
        $this->handler->expectOnce('startElement', array('br', array()));
        $this->parser->parse('content<br>');
    }

    function testStartElementWithPostContent() {
        $this->handler->expectOnce('startElement', array('br', array()));
        $this->handler->expectOnce('characters', array('content'));
        $this->parser->parse('<br>content');
    }

    function testMismatchedElements() {
        $this->handler->expectArgumentsAt(0, 'startElement', array('b', array()));
        $this->handler->expectArgumentsAt(1, 'startElement', array('i', array()));
        $this->handler->expectArgumentsAt(0, 'endElement', array('b'));
        $this->handler->expectArgumentsAt(1, 'endElement', array('i'));
        $this->handler->expectCallCount('startElement', 2);
        $this->handler->expectCallCount('endElement', 2);
        $this->handler->expectOnce('characters', array('content'));
        $this->parser->parse('<b><i>content</b></i>');
    }

    function testEndElement() {
        $this->handler->expectOnce('endElement', array('tag'));
        $this->handler->expectNever('characters');
        $this->parser->parse('</tag>');
    }

    function testEndElementWithPreContent() {
        $this->handler->expectOnce('characters', array('a'));
        $this->handler->expectOnce('endElement', array('tag'));
        $this->parser->parse('a</tag>');
    }

    function testEndElementWithPostContent() {
        $this->handler->expectOnce('endElement', array('tag'));
        $this->handler->expectOnce('characters', array('a'));
        $this->parser->parse('</tag>a');
    }

    function testEndElementWithSpace() {
        $this->handler->expectOnce('endElement', array('tag'));
        $this->handler->expectNever('characters');
        $this->parser->parse('</tag >');
    }

    function testEmptyElementSelfClose() {
        $this->handler->expectOnce('emptyElement', array('br', array()));
        $this->handler->expectNever('startElement');
        $this->handler->expectNever('endElement');
        $this->handler->expectNever('characters');
        $this->parser->parse('<br/>');
    }

    function testEmptyElementSelfCloseWithSpace() {
        $this->handler->expectOnce('emptyElement', array('br', array()));
        $this->handler->expectNever('startElement');
        $this->handler->expectNever('endElement');
        $this->handler->expectNever('characters');
        $this->parser->parse('<br />');
    }

    function testElementNestedSingleQuote() {
        $this->handler->expectOnce('startElement', array('tag', array('attribute' => '\'')));
        $this->handler->expectNever('characters');
        $this->handler->expectNever('endElement');
        $this->parser->parse('<tag attribute="\'">');
    }

    function testElementNestedDoubleQuote() {
        $this->handler->expectOnce('startElement', array('tag', array('attribute' => '"')));
        $this->handler->expectNever('characters');
        $this->handler->expectNever('endElement');
        $this->parser->parse('<tag attribute=\'"\'>');
    }

    function testAttributes() {
        $this->handler->expectOnce(
                'startElement',
                array('tag', array("a" => "A", "b" => "B", "c" => "C")));
        $this->handler->expectNever('characters');
        $this->parser->parse('<tag a="A" b=\'B\' c = "C">');
    }

    function testEmptyAttributes() {
        $this->handler->expectOnce(
                'startElement',
                array('tag', array("a" => NULL, "b" => NULL, "c" => NULL)));
        $this->handler->expectNever('characters');
        $this->parser->parse('<tag a b c>');
    }

    function testNastyAttributes() {
        $this->handler->expectOnce(
                'startElement',
                array('tag', array("a" => "&%$'?<>", "b" => "\r\n\t\"", "c" => "")));
        $this->handler->expectNever('characters');
        $this->parser->parse("<tag a=\"&%$'?<>\" b='\r\n\t\"' c = ''>");
    }

    function testAttributesPadding() {
        $this->handler->expectOnce(
                'startElement',
                array('tag', array("a" => "A", "b" => "B", "c" => "C")));
        $this->handler->expectNever('characters');
        $this->parser->parse("<tag\ta=\"A\"\rb='B'\nc = \"C\"\n>");
    }
 
    function testTruncatedOpen() {
        $this->handler->expectOnce('characters', array('content<'));
        $this->handler->expectNever('startElement');
        $this->parser->parse('content<');
    }

    function testTruncatedEmptyClose() {
        $this->handler->expectOnce('characters', array('content</'));
        $this->handler->expectNever('endElement');
        $this->parser->parse('content</');
    }

    function testTruncatedClose() {
        $this->handler->expectOnce('characters', array('content</a'));
        $this->parser->parse('content</a');
        $this->handler->expectNever('endElement');
    }

    function testTruncatedOpenElementChar() {
        $this->handler->expectOnce('characters', array('content<a'));
        $this->handler->expectNever('startElement');
        $this->parser->parse('content<a');
    }

    function testTruncatedOpenElement() {
        $this->handler->expectOnce('characters', array('content<tag'));
        $this->handler->expectNever('startElement');
        $this->parser->parse('content<tag');
    }

    function testTruncatedOpenElementSpace() {
        $this->handler->expectOnce('characters', array('content<tag '));
        $this->handler->expectNever('startElement');
        $this->parser->parse('content<tag ');
    }

    function testTruncatedOpenElementMinimizedAttribute() {
        $this->handler->expectOnce('characters', array('content<tag attribute'));
        $this->handler->expectNever('startElement');
        $this->parser->parse('content<tag attribute');
    }

    function testTruncatedOpenElementMinimizedAttributeSpace() {
        $this->handler->expectOnce('characters', array('content<tag attribute '));
        $this->handler->expectNever('startElement');
        $this->parser->parse('content<tag attribute ');
    }

    function testTruncatedOpenElementAttribute() {
        $this->handler->expectOnce('characters', array('content<tag attribute='));
        $this->handler->expectNever('startElement');
        $this->parser->parse('content<tag attribute=');
    }

    function testTruncatedOpenElementAttributeSpace() {
        $this->handler->expectOnce('characters', array('content<tag attribute= '));
        $this->handler->expectNever('startElement');
        $this->parser->parse('content<tag attribute= ');
    }

    function testTruncatedOpenElementAttributeNoQuote() {
        $this->handler->expectOnce('characters', array('content<tag attribute=value'));
        $this->handler->expectNever('startElement');
        $this->parser->parse('content<tag attribute=value');
    }

    function testTruncatedOpenElementAttributeDoubleQuote() {
        $this->handler->expectOnce('characters', array('content<tag attribute="'));
        $this->handler->expectNever('startElement');
        $this->parser->parse('content<tag attribute="');
    }

    function testTruncatedOpenElementAttributeDoubleQuoteNoClose() {
        $this->handler->expectOnce('characters', array('content<tag attribute="value'));
        $this->handler->expectNever('startElement');
        $this->parser->parse('content<tag attribute="value');
    }

    function testTruncatedOpenElementAttributeDoubleQuoteValue() {
        $this->handler->expectOnce('characters', array('content<tag attribute="value"'));
        $this->handler->expectNever('startElement');
        $this->parser->parse('content<tag attribute="value"');
    }

    function testTruncatedOpenElementAttributeSingleQuote() {
        $this->handler->expectOnce('characters', array('content<tag attribute=\''));
        $this->handler->expectNever('startElement');
        $this->parser->parse('content<tag attribute=\'');
    }

    function testTruncatedOpenElementAttributeSingleQuoteNoClose() {
        $this->handler->expectOnce('characters', array('content<tag attribute=\'value'));
        $this->handler->expectNever('startElement');
        $this->parser->parse('content<tag attribute=\'value');
    }

    function testTruncatedOpenElementAttributeSingleQuoteValue() {
        $this->handler->expectOnce('characters', array('content<tag attribute=\'value\''));
        $this->handler->expectNever('startElement');
        $this->parser->parse('content<tag attribute=\'value\'');
    }

    function testTruncatedOpenElementClose() {
        $this->handler->expectOnce('characters', array('content<tag attribute=\'value\'/'));
        $this->handler->expectNever('startElement');
        $this->parser->parse('content<tag attribute=\'value\'/');
    }
 
}

/*
*   These test cases are valid HTML markup
*/
class HtmlSaxReaderProcessingInstructionMarkupTestCase extends WactSaxTestCase {

    function createParser() {
        return new Wact_Html_Sax_Parser();
    }

    function testTargetOnlyProcessingInstruction() {
        $this->handler->expectOnce('characters', array('<?php ?>'));
        $this->parser->parse('<?php ?>');
    }

    function testAllprocessingInstruction() {
        $this->handler->expectOnce('characters', array('<?php print "Hello"; ?>'));
        $this->handler->expectNever('startElement');
        $this->handler->expectNever('endElement');
        $this->parser->parse('<?php print "Hello"; ?>');
    }

    function testNestedprocessingInstruction() {
        $this->handler->expectOnce('characters', array('a<?php print "Hello"; ?>b'));
        $this->handler->expectNever('startElement');
        $this->handler->expectNever('endElement');
        $this->parser->parse('a<?php print "Hello"; ?>b');
    }

    function testTruncatedProcessingInstruction() {
        $this->handler->expectOnce('characters', array('content<?'));
        $this->handler->expectNever('startElement');
        $this->parser->parse('content<?');
    }

    function testMalformedProcessingInstruction() {
        $this->handler->expectOnce('characters', array('content<?>'));
        $this->parser->parse('content<?>');
    }

    function testMalformedProcessingInstruction2() {
        $this->handler->expectOnce('characters', array('<??>'));
        $this->parser->parse('<??>');
    }

    function testTruncatedProcessingInstructionTarget() {
        $this->handler->expectOnce('characters', array('content<?php'));
        $this->handler->expectNever('startElement');
        $this->parser->parse('content<?php');
    }

    function testTruncatedProcessingInstructionNoClose() {
        $this->handler->expectOnce('characters', array('content<?php '));
        $this->handler->expectNever('startElement');
        $this->parser->parse('content<?php ');
    }
    
    function testXmlDecl() {
        $this->parser->parse('<?xml version="1.0"?>');
    }

    function testXmlDeclWithEncoding() {
        $this->parser->parse('<?xml version="1.0" encoding="UTF-8" ?>');
    }

    function testXmlDeclWithStandalone() {
        $this->parser->parse('<?xml version="1.0" standalone="yes" ?>');
    }

    function testXmlDeclWithEncodingAndStandalone() {
        $this->parser->parse('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>');
    }

    // Much evil remains to be perpatrated via invalid xml declarations.

}

class HtmlSaxReaderCommentTestCase extends WactSaxTestCase {

    function createParser() {
        return new Wact_Html_Sax_Parser();
    }

    /*
    *   HTML 4.0:   Valid Markup 
    *   XML 1.1:    Valid Markup
    */
    function testEmptyComment() {
        $this->handler->expectOnce('comment', array(''));
        $this->handler->expectNever('characters');
        $this->parser->parse('<!---->');
    }

    /*
    *   HTML 4.0:   Valid Markup see http://www.w3.org/MarkUp/SGML/sgml-lex/sgml-lex
    *   XML 1.1:    Valid Markup
    */
    function testSimpleComment() {
        $this->handler->expectOnce('comment', array(' xyz '));
        $this->parser->parse('<!-- xyz -->');
    }

    /*
    *   HTML 4.0:   Valid Markup 
    *   XML 1.1:    Valid Markup
    */
    function testNastyComment() {
        $this->handler->expectOnce(
                'comment',
                array(' <tag></tag><?php ?><' . '% %> '));
        $this->handler->expectNever('characters');
        $this->parser->parse('<tag><!-- <tag></tag><?php ?><' . '% %> --></tag>');
    }

    /*
    *   XML 1.1:    Not well-formed see http://www.w3.org/TR/xml11/#sec-comments
    */
    function testNotWellFormedComment() {
        $this->handler->expectOnce('characters', array('<!-- B+, B, or B--->'));
        $this->handler->expectNever('comment');
        $this->parser->parse('<!-- B+, B, or B--->');
    }

    /*
    *   HTML 4.0:   Valid Markup see http://www.w3.org/MarkUp/SGML/sgml-lex/sgml-lex
    *   XML 1.1:    Not well-formed see http://www.w3.org/TR/xml11/#sec-comments
    */
    function testCompoundComment() {
        $this->handler->expectOnce('comment', array(array(' xyz ', 'def')));
        $this->parser->parse('<!-- xyz -- --def-->');
    }

    /*
    *   HTML 4.0:   Valid Markup see http://www.w3.org/MarkUp/SGML/sgml-lex/sgml-lex
    *   XML 1.1:    Not well-formed see http://www.w3.org/TR/xml11/#sec-comments
    */
    function testCompoundComment2() {
        $this->handler->expectOnce('comment', array(array('', '', '')));
        $this->parser->parse('<!---- ---- ---->');
    }

    /*
    *   HTML 4.0:   Valid Markup see http://www.w3.org/MarkUp/SGML/sgml-lex/sgml-lex
    *   XML 1.1:    Not well-formed see http://www.w3.org/TR/xml11/#sec-comments
    */
    function testCompoundComment3() {
        $this->handler->expectOnce('comment', array(array('', '', '')));
        $this->parser->parse('<!------------>');
    }

    /*
    *   HTML 4.0:   Invalid Markup see http://www.w3.org/MarkUp/SGML/sgml-lex/sgml-lex
    *   XML 1.1:    Not well-formed see http://www.w3.org/TR/xml11/#sec-comments
    */
    function testMalformedComment() {
        $this->handler->expectOnce('characters', array('<!--x->'));
        $this->handler->expectNever('comment');
        $this->parser->parse('<!--x->');
    }

    /*
    *   HTML 4.0:   Invalid Markup see http://www.w3.org/MarkUp/SGML/sgml-lex/sgml-lex
    *   XML 1.1:    Not well-formed see http://www.w3.org/TR/xml11/#sec-comments
    */
    function testMalformedComment2() {
        $this->handler->expectOnce('characters', array('<!-- comment-- xxx>'));
        $this->handler->expectNever('comment');
        $this->parser->parse('<!-- comment-- xxx>');
    }

    /*
    *   HTML 4.0:   Invalid Markup see http://www.w3.org/MarkUp/SGML/sgml-lex/sgml-lex
    *   XML 1.1:    Not well-formed see http://www.w3.org/TR/xml11/#sec-comments
    */
    function testMalformedComment3() {
        $this->handler->expectOnce('characters', array('<!-- comment -- ->'));
        $this->handler->expectNever('comment');
        $this->parser->parse('<!-- comment -- ->');
    }

    /*
    *   HTML 4.0:   Invalid Markup see http://www.w3.org/MarkUp/SGML/sgml-lex/sgml-lex
    *   XML 1.1:    Not well-formed see http://www.w3.org/TR/xml11/#sec-comments
    */
    function testMalformedComment4() {
        $this->handler->expectOnce('characters', array('<!----->'));
        $this->handler->expectNever('comment');
        $this->parser->parse('<!----->');
    }

    /*
    *   HTML 4.0:   Valid markup 
    *   XML 1.1:    Not well-formed see http://www.w3.org/TR/xml11/#sec-comments
    *
    *   see http://www.hixie.ch/tests/adhoc/html/parsing/compat/008.html
    */
    function testCommentedTag() {
        $this->handler->expectOnce('comment', array('><span><!'));
        $this->handler->expectNever('startElement');
        $this->parser->parse('<!--><span><!-->');
    }

    /*
    *   HTML 4.0:   Valid markup 
    *   XML 1.1:    Not well-formed see http://www.w3.org/TR/xml11/#sec-comments
    *
    *   see http://www.hixie.ch/tests/adhoc/html/parsing/comments/001.html
    */
    function testNextedCommentConfusion() {
        $this->handler->expectArgumentsAt(0, 'comment', array(array('', '><!')));
        $this->handler->expectArgumentsAt(1, 'comment', array(array('', '-><!')));
        $this->handler->expectCallCount('comment', 2);
        $this->handler->expectOnce('characters', array('PASS'));
        $this->handler->expectNever('startElement');
        $this->parser->parse('<!------><!-->PASS<!-------><!-->');
    }

    /*
    *   HTML 4.0:   Invalid Markup
    *   XML 1.1:    Not well-formed
    *
    *   see http://www.hixie.ch/tests/adhoc/html/parsing/comments/002.html
    */
    function testMalformedComment5() {
        $this->handler->expectOnce('characters', array('<!-- --FAIL>'));
        $this->handler->expectNever('comment');
        $this->parser->parse('<!-- --FAIL>');
    }
    
    /*
    *   HTML 4.0:   Invalid Markup
    *   XML 1.1:    Not well-formed
    *
    *   see http://www.hixie.ch/tests/adhoc/html/parsing/comments/003.html
    */
    function testMalformedComment6() {
        $this->handler->expectOnce('characters', array('<!-- --- FAIL --- -->'));
        $this->handler->expectNever('comment');
        $this->parser->parse('<!-- --- FAIL --- -->');
    }
    
    /*
    *   HTML 4.0:   Valid Markup
    *   XML 1.1:    Not well-formed
    *
    *   see http://www.hixie.ch/tests/evil/mixed/comments-evil.html    
    */
    function testCompoundComment7() {
        $this->handler->expectOnce('comment', array(' ->incorrect<!- '));
        $this->handler->expectNever('characters');
        $this->parser->parse('<!-- ->incorrect<!- -->');
    }

    /*
    *   HTML 4.0:   Valid Markup
    *   XML 1.1:    Not well-formed
    *
    *   see http://www.hixie.ch/tests/evil/mixed/comments-evil.html    
    */
    function testCompoundComment8() {
        $this->handler->expectOnce('comment', array(array(' ', '>incorrect<!', '')));
        $this->handler->expectNever('characters');
        $this->parser->parse('<!-- ---->incorrect<!------>');
    }

    /*
    *   HTML 4.0:   Valid Markup
    *   XML 1.1:    Not well-formed
    *
    *   see http://www.hixie.ch/tests/evil/mixed/comments-evil.html    
    */
    function testCompoundComment9() {
        $this->handler->expectOnce('comment', array(array('', '>incorrect<!', '')));
        $this->handler->expectNever('characters');
        $this->parser->parse('<!------>incorrect<!------>');
    }

    /*
    *   HTML 4.0:   Valid Markup
    *   XML 1.1:    Not well-formed
    *
    *   see http://www.hixie.ch/tests/evil/mixed/comments-evil.html    
    */
    function testCompoundComment10() {
        $this->handler->expectOnce('comment', array(array('', '>incorrect<!', '')));
        $this->handler->expectNever('characters');
        $this->parser->parse('<!---- -->incorrect<!------>');
    }

    /*
    *   HTML 4.0:   Valid Markup
    *   XML 1.1:    Not well-formed
    *
    *   see http://www.hixie.ch/tests/evil/mixed/comments-evil.html    
    */
    function testCompoundComment11() {
        $this->handler->expectOnce('comment', array(array(' ', '>incorrect<!', ' ')));
        $this->handler->expectNever('characters');
        $this->parser->parse('<!-- -- -->incorrect<!-- -- -->');
    }

    /*
    */
    function testTruncatedComment() {
        $this->handler->expectOnce('characters', array('content<!--'));
        $this->handler->expectNever('comment');
        $this->parser->parse('content<!--');
    }
    
    /*
    */
    function testTruncatedCommentNoClose() {
        $this->handler->expectOnce('characters', array('content<!-- blah'));
        $this->handler->expectNever('comment');
        $this->parser->parse('content<!-- blah');
    }

}

class HtmlSaxReaderCdataTestCase extends WactSaxTestCase {

    function createParser() {
        return new Wact_Html_Sax_Parser();
    }

    function testCData() {
        $this->handler->expectOnce(
            'cdata',
            array('string = \'A CDATA block\';'));
        $this->parser->parse('<![CDATA[string = \'A CDATA block\';]]>');
    }

    function testCData2() {
        $this->handler->expectOnce(
            'cdata',
            array('<tag>'));
        $this->parser->parse('<![CDATA[<tag>]]>');
    }

    function testCDataPrePost() {
        $this->handler->expectArgumentsAt(0, 'characters', array('abc'));
        $this->handler->expectArgumentsAt(1, 'cdata', array('string = \'A CDATA block\';'));
        $this->handler->expectArgumentsAt(2, 'characters', array('def'));

        $this->parser->parse('abc<![CDATA[string = \'A CDATA block\';]]>def');
    }

}

/*
* These cases are valid HTML Markup syntax, but they do not generate markup events
* in our SaxReader implementation
* 
* SGML Short tag syntax
*
* Empty start-tag :
*   <UL>
*       <LI>  this is the first item of the list
*       <>  this is second one -- implied identifier is LI
*   </>
* 
* Empty end-tag:
*   Some <B>bold text with empty end tag </> -- right here.
* 
* Unclosed tags :
*   This text is <b<i> bold and italic at once </b</i>.
* 
* Null-end tags :
*   <H1/Header with null-end tag/
* 
*/
class HtmlSaxReaderValidHtmlMarkupTestCase extends WactSaxTestCase {

    function createParser() {
        return new Wact_Html_Sax_Parser();
    }

    function testEmptyClose() {
        $this->handler->expectOnce('characters', array('</>'));
        $this->handler->expectNever('endElement');
        $this->parser->parse('</>');
    }

}

/*
*   malformed Markup
*/
class HtmlSaxReaderMalformedTestCase extends WactSaxTestCase {

    function createParser() {
        return new Wact_Html_Sax_Parser();
    }

    function testOpenElementMalformedClose() {
        $this->handler->expectOnce('characters', array('content<tag attribute=\'value\'/morecontent'));
        $this->handler->expectNever('startElement');
        $this->parser->parse('content<tag attribute=\'value\'/morecontent');
    }

    function testOpenElementMalformedClose2() {
        $this->handler->expectOnce('startElement', array('tag', array('attribute' => '\'value\'/morecontent')));
        $this->handler->expectOnce('characters', array('content'));
        $this->parser->parse('content<tag attribute=\'value\'/morecontent>');
    }

    function testElementNestedSingleQuote() {
        $this->handler->expectOnce('startElement', array('tag', array('attribute' => '\'')));
        $this->handler->expectNever('characters');
        $this->handler->expectNever('endElement');
        $this->parser->parse('<tag attribute=\'\'\'>');
    }

    function testElementNestedDoubleQuote() {
        $this->handler->expectOnce('startElement', array('tag', array('attribute' => '"')));
        $this->handler->expectNever('characters');
        $this->handler->expectNever('endElement');
        $this->parser->parse('<tag attribute=""">');
    }

    function testElementMalformedAttribute() {
        $this->handler->expectOnce('startElement', array('tag', array('attribute' => '"test"extra')));
        $this->handler->expectNever('characters');
        $this->handler->expectNever('endElement');
        $this->parser->parse('<tag attribute="test"extra>');
    }

    function testNotAnEndElementWithSpace() {
        $this->handler->expectOnce('characters', array('< /tag>'));
        $this->parser->parse('< /tag>');
    }

}

    /* 
    removed due to bug #1000806
    see http://www.w3.org/TR/REC-html40/appendix/notes.html#notes-specifying-data
    function testScriptElement() {
        $this->handler->expectOnce('startElement', array('script', array('language'=>'Javascript')));
        $this->handler->expectOnce('endElement', array('script'));
        $this->handler->expectOnce('characters', array("document.write('<B>Test<\/B>');"));
        $this->parser->parse('<script language="Javascript">document.write(\'<B>Test<\/B>\');</script>');
    }

    function testScriptElementEmbedComment() {
        $this->handler->expectOnce('startElement', array('script', array('language'=>'Javascript')));
        $this->handler->expectOnce('endElement', array('script'));
        $this->handler->expectOnce('characters', array("<!-- document.write('<B>Test<\/B>'); -->"));
        $this->parser->parse('<script language="Javascript"><!-- document.write(\'<B>Test<\/B>\'); --></script>');
    }
    */


?>