events[] = array('characters', $text, $location); } function startTag($tag, $attributes, $location) { $this->events[] = array('startTag', $tag, $attributes, $location); } function endTag($tag, $location) { $this->events[] = array('endTag', $tag, $location); } function emptyTag($tag, $attributes, $location) { $this->events[] = array('emptyTag', $tag, $attributes, $location); } function instruction($type, $code, $location) { $this->events[] = array('instruction', $type, $code, $location); } } class WactHTMLParserTest extends UnitTestCase { protected $parser; protected $listener; function setUp() { $this->listener = new WactHTMLParserListenerStub(); $this->parser = new WactHTMLParser($this->listener); $this->file_name = 'my_file'; } protected function _createLocation($line = 1) { return new WactSourceLocation('my_file', $line); } function testEmpty() { $this->parser->parse('', $this->file_name); $this->assertEqual($this->listener->events, array()); } function testSimpleDataIsCharacters() { $location = $this->_createLocation(); $this->parser->parse('stuff', $this->file_name); $this->checkEventsCount(1); $this->checkCharactersEvent(0, 'stuff', $location); } function testPreservingWhiteSpace() { $this->parser->parse(" stuff\t\r\n ", $this->file_name); $this->checkEventsCount(1); $this->checkCharactersEvent(0, " stuff\t\r\n "); } function testTagWithNoContentNoAttributes() { $location = $this->_createLocation(); $this->parser->parse('', $this->file_name); $this->checkEventsCount(2); $this->checkStartTagEvent(0, "tag", array(), $location); $this->checkEndTagEvent(1, "tag", $location); } function testEmptyTag() { $location = $this->_createLocation(); $this->parser->parse('
', $this->file_name); $this->checkEventsCount(1); $this->checkEmptyTagEvent(0, "br", array(), $location); } function testTagWithContent() { $this->parser->parse('stuff', $this->file_name); $this->checkEventsCount(3); $this->checkStartTagEvent(0, "tag", array()); $this->checkCharactersEvent(1, "stuff"); $this->checkEndTagEvent(2, "tag"); } function testEmptyComment() { $this->parser->parse('', $this->file_name); $this->checkEventsCount(1); $this->checkCharactersEvent(0, ""); } function testTruncatedComment() { $location = $this->_createLocation(); $this->parser->parse('stuff'); $this->checkEventsCount(3); $this->checkStartTagEvent(0, "script", array('language' => "Javascript")); $this->checkCharactersEvent(1, ''); $this->checkEndTagEvent(2, "script"); } function testTruncatedOpenTagChar() { $location = $this->_createLocation(); $this->parser->parse('stufffile_name); $this->checkEventsCount(2); $this->checkCharactersEvent(0, 'stuff', $location); $this->checkCharactersEvent(1, '_createLocation(); $this->parser->parse('stufffile_name); $this->checkCharactersEvent(0, 'stuff', $location); $this->checkCharactersEvent(1, '_createLocation(); $this->parser->parse('stufffile_name); $this->checkCharactersEvent(0, 'stuff', $location); $this->checkCharactersEvent(1, '_createLocation(); $this->parser->parse('stufffile_name); $this->checkCharactersEvent(0, 'stuff', $location); $this->checkCharactersEvent(1, '_createLocation(); $this->parser->parse('stufffile_name); $this->checkCharactersEvent(0, 'stuff', $location); $this->checkCharactersEvent(1, '_createLocation(); $this->parser->parse('stuffcheckCharactersEvent(1, 'checkCharactersEvent(1, 'file_name); $this->checkCharactersEvent(0, 'stuff', $location); $this->checkCharactersEvent(1, '_createLocation(); $this->parser->parse('stuff_createLocation(); $this->parser->parse('stuff_createLocation(); $this->parser->parse('stufffile_name); $this->checkCharactersEvent(0, 'stuff', $location); $this->checkCharactersEvent(1, '_createLocation(); $this->parser->parse('stufffile_name); $this->checkCharactersEvent(0, 'stuff', $location); $this->checkCharactersEvent(1, '_createLocation(); $this->parser->parse('stufffile_name); $this->checkCharactersEvent(0, 'stuff', $location); $this->checkCharactersEvent(1, '_createLocation(); $this->parser->parse('stufffile_name); $this->checkCharactersEvent(0, 'stuff', $location); $this->checkCharactersEvent(1, '_createLocation(); $this->parser->parse('stufffile_name); $this->checkCharactersEvent(0, 'stuff', $location); $this->checkCharactersEvent(1, '_createLocation(); $this->parser->parse('', $this->file_name); $this->checkEventsCount(1); $this->checkCharactersEvent(0, '', $location); } function testProcessDoctypeAsCharacters() { $this->parser->parse('', $this->file_name); $this->checkEventsCount(1); $this->checkCharactersEvent(0, ''); } function testNestedDoctypeHandler() { $this->parser->parse('ab'); $this->checkEventsCount(2); $this->checkCharactersEvent(0, 'a'); $this->checkCharactersEvent(1, 'b'); } function testTruncatedDocType() { $location = $this->_createLocation(); $this->parser->parse('stufffile_name); $this->checkEventsCount(2); $this->checkCharactersEvent(0, 'stuff', $location); $this->checkCharactersEvent(1, '_createLocation(); $this->parser->parse('stufffile_name); $this->checkEventsCount(2); $this->checkCharactersEvent(0, 'stuff', $location); $this->checkCharactersEvent(1, '_createLocation(); $this->parser->parse('', $this->file_name); $this->checkEventsCount(1); $this->checkCharactersEvent(0, '', $location); } function testCommentWithContent() { $location = $this->_createLocation(); $this->parser->parse('', $this->file_name); $this->checkEventsCount(1); $this->checkCharactersEvent(0, '', $location); } function testCommentIgnoresAnyTagsOrInstructions() { $this->parser->parse(''); $this->checkEventsCount(3); $this->checkStartTagEvent(0, 'tag', array()); $this->checkCharactersEvent(1, ''); $this->checkEndTagEvent(2, 'tag'); } function testJSComparisonSymbolIsNotATag() { $location = $this->_createLocation(); $this->parser->parse('', $this->file_name); $this->checkEventsCount(4); $this->checkStartTagEvent(0, 'script', array(), $location); $this->checkCharactersEvent(1, ' for(var i=0; i ', $location); $this->checkCharactersEvent(2, '< 10; i++){ document.write(">");} ', $location); $this->checkEndTagEvent(3, 'script', $location); } function testJSComparisonSymbolIsNotATag2() { $location = $this->_createLocation(); $this->parser->parse('', $this->file_name); $this->checkEventsCount(4); $this->checkStartTagEvent(0, 'script', array(), $location); $this->checkCharactersEvent(1, ' for(var i=0; i ', $location); $this->checkCharactersEvent(2, '<= 10; i++){ document.write(">");} ', $location); $this->checkEndTagEvent(3, 'script', $location); } function testEmptyJasp() { $location = $this->_createLocation(); $this->parser->parse('<%%>', $this->file_name); $this->checkEventsCount(1); $this->checkCharactersEvent(0, '<%%>', $location); } function testMalformedJasp() { $location = $this->_createLocation(); $this->parser->parse('stuff<%>', $this->file_name); $this->checkEventsCount(2); $this->checkCharactersEvent(0, 'stuff', $location); $this->checkCharactersEvent(1, '<%>', $location); } function testSimpleJasp() { $this->parser->parse('<' . '% document.write("Hello World");%>'); $this->checkEventsCount(1); $this->checkCharactersEvent(0, '<% document.write("Hello World");%>'); } function testNastyJasp() { $this->parser->parse('<' . '% %>'); $this->checkEventsCount(6); $this->checkCharactersEvent(0, '<% '); $this->checkStartTagEvent(1, 'tag', array('a' => 'A')); $this->checkInstructionEvent(2, 'php', ''); $this->checkEndTagEvent(3, 'tag'); $this->checkCharactersEvent(4, ''); $this->checkCharactersEvent(5, ' %>'); } function testJaspInTag() { $this->parser->parse('<' . '% document.write("Hello World");%>'); $this->checkStartTagEvent(0, 'tag', array()); $this->checkCharactersEvent(1, '<% document.write("Hello World");%>'); $this->checkEndTagEvent(2, 'tag'); } function testTruncatedJasp() { $location = $this->_createLocation(); $this->parser->parse('stuff<%', $this->file_name); $this->checkEventsCount(2); $this->checkCharactersEvent(0, 'stuff', $location); $this->checkCharactersEvent(1, '<%', $location); } function testTruncatedJaspNoClose() { $location = $this->_createLocation(); $this->parser->parse('stuff<% more stuff', $this->file_name); $this->checkEventsCount(2); $this->checkCharactersEvent(0, 'stuff', $location); $this->checkCharactersEvent(1, '<% more stuff', $location); } function testEmptyCloseTag() { $this->parser->parse('', $this->file_name); $this->checkEventsCount(1); $this->checkEndTagEvent(0, '', array()); } function testProcessingInstruction() { $location = $this->_createLocation(); $this->parser->parse('', $this->file_name); $this->checkEventsCount(1); $this->checkInstructionEvent(0, 'php', '', $location); } function testAllProcessingInstruction() { $this->parser->parse('', $this->file_name); $this->checkEventsCount(1); $this->checkInstructionEvent(0, 'php', 'print "Hello"; '); } function testNestedProcessingInstruction() { $this->parser->parse('ab', $this->file_name); $this->checkEventsCount(3); $this->checkCharactersEvent(0, 'a'); $this->checkInstructionEvent(1, 'php', 'print "Hello"; '); $this->checkCharactersEvent(2, 'b'); } function testTruncatedOpen() { $location = $this->_createLocation(); $this->parser->parse('stuff<', $this->file_name); $this->checkEventsCount(2); $this->checkCharactersEvent(0, 'stuff', $location); $this->checkCharactersEvent(1, '<', $location); } function testTruncatedEmptyClose() { $location = $this->_createLocation(); $this->parser->parse('stufffile_name); $this->checkEventsCount(2); $this->checkCharactersEvent(0, 'stuff', $location); $this->checkCharactersEvent(1, '_createLocation(); $this->parser->parse('stufffile_name); $this->checkEventsCount(2); $this->checkCharactersEvent(0, 'stuff', $location); $this->checkCharactersEvent(1, '_createLocation(); $this->parser->parse('stufffile_name); $this->checkEventsCount(2); $this->checkCharactersEvent(0, 'stuff', $location); $this->checkCharactersEvent(1, '_createLocation(); $this->parser->parse('stufffile_name); $this->checkEventsCount(2); $this->checkCharactersEvent(0, 'stuff', $location); $this->checkCharactersEvent(1, '_createLocation(); $this->parser->parse('stuff', $this->file_name); $this->checkEventsCount(2); $this->checkCharactersEvent(0, 'stuff', $location); $this->checkCharactersEvent(1, '', $location); } function testMalformedProcessingInstruction2() { $location = $this->_createLocation(); $this->parser->parse('stuff', $this->file_name); $this->checkEventsCount(2); $this->checkCharactersEvent(0, 'stuff', $location); $this->checkCharactersEvent(1, '', $location); } function checkEventsCount($count) { $this->assertEqual(sizeof($this->listener->events), $count); } function checkCharactersEvent($event_index, $characters, $location = null) { $event = $this->listener->events[$event_index]; $this->assertEqual($event[0], 'characters'); $this->assertEqual($event[1], $characters); if($location) $this->assertEqual($event[2], $location); } function checkStartTagEvent($event_index, $tag, $attributes, $location = null) { $event = $this->listener->events[$event_index]; $this->assertEqual($event[0], 'startTag'); $this->assertEqual($event[1], $tag); $this->assertEqual($event[2], $attributes); if($location) $this->assertEqual($event[3], $location); } function checkEndTagEvent($event_index, $tag, $location = null) { $event = $this->listener->events[$event_index]; $this->assertEqual($event[0], 'endTag'); $this->assertEqual($event[1], $tag); if($location) $this->assertEqual($event[2], $location); } function checkEmptyTagEvent($event_index, $tag, $attributes, $location = null) { $event = $this->listener->events[$event_index]; $this->assertEqual($event[0], 'emptyTag'); $this->assertEqual($event[1], $tag); $this->assertEqual($event[2], $attributes); if($location) $this->assertEqual($event[3], $location); } function checkInstructionEvent($event_index, $type, $code, $location = null) { $event = $this->listener->events[$event_index]; $this->assertEqual($event[0], 'instruction'); $this->assertEqual($event[1], $type); $this->assertEqual($event[2], $code); if($location) $this->assertEqual($event[3], $location); } } ?>