assertEquals($type, $event['name'], "Event $type for " . print_r($event, TRUE));
if (is_array($expects)) {
$this->assertEquals($expects, $event['data'], "Event $type should equal $expects: " . print_r($event, TRUE));
}
else {
$this->assertEquals($expects, $event['data'][0], "Event $type should equal $expects: " . print_r($event, TRUE));
}
}
/**
* Assert that a given event is 'error'.
*/
public function assertEventError($event) {
$this->assertEquals('error', $event['name'], "Expected error for event: " . print_r($event, TRUE));
}
/**
* Asserts that all of the tests are good.
*
* This loops through a map of tests/expectations and runs a few assertions on each test.
*
* Checks:
* - depth (if depth is > 0)
* - event name
* - matches on event 0.
*/
protected function isAllGood($name, $depth, $tests, $debug = FALSE) {
foreach ($tests as $try => $expects) {
if ($debug) {
fprintf(STDOUT, "%s expects %s\n", $try, print_r($expects, TRUE));
}
$e = $this->parse($try);
if ($depth > 0) {
$this->assertEquals($depth, $e->depth(), "Expected depth $depth for test $try." . print_r($e, TRUE));
}
$this->assertEventEquals($name, $expects, $e->get(0));
}
}
// ================================================================
// Utility functions.
// ================================================================
public function testParse() {
list($tok, $events) = $this->createTokenizer('');
$tok->parse();
$e1 = $events->get(0);
$this->assertEquals(1, $events->Depth());
$this->assertEquals('eof', $e1['name']);
}
public function testWhitespace() {
$spaces = ' ';
list($tok, $events) = $this->createTokenizer($spaces);
$tok->parse();
$this->assertEquals(2, $events->depth());
$e1 = $events->get(0);
$this->assertEquals('text', $e1['name']);
$this->assertEquals($spaces, $e1['data'][0]);
}
public function testCharacterReference() {
$good = array(
'&' => '&',
'<' => '<',
'&' => '&',
'&' => '&',
);
$this->isAllGood('text', 2, $good);
// Test with broken charref
$str = '&foo';
$events = $this->parse($str);
$e1 = $events->get(0);
$this->assertEquals('error', $e1['name']);
$str = 'oo';
$events = $this->parse($str);
$e1 = $events->get(0);
$this->assertEquals('error', $e1['name']);
$str = 'foo';
$events = $this->parse($str);
$e1 = $events->get(0);
$this->assertEquals('error', $e1['name']);
// FIXME: Once the text processor is done, need to verify that the
// tokens are transformed correctly into text.
}
public function testBogusComment() {
$bogus = array(
'+this is a bogus comment. +>',
'',
'',
'',
'',
'',
'',
'',
'',
' Hello World',
);
foreach ($bogus as $str) {
$events = $this->parse($str);
$this->assertEventError($events->get(0));
$this->assertEventEquals('comment', $str, $events->get(1));
}
}
public function testEndTag() {
$succeed = array(
'' => 'a',
'' => 'test',
'' => 'test',
'' =>
'thisIsTheTagThatDoesntEndItJustGoesOnAndOnMyFriend',
// See 8.2.4.10, which requires this and does not say error.
'' => 'aisAllGood('endTag', 2, $succeed);
// Recoverable failures
$fail = array(
'' => 'a',
'' => 'a',
'' => 'a',
'' => 'a',
' 'a',
);
foreach ($fail as $test => $result) {
$events = $this->parse($test);
$this->assertEquals(3, $events->depth());
// Should have triggered an error.
$this->assertEventError($events->get(0));
// Should have tried to parse anyway.
$this->assertEventEquals('endTag', $result, $events->get(1));
}
// BogoComments
$comments = array(
'>' => '>',
' >' => ' >',
' a>' => ' a>',
);
foreach ($comments as $test => $result) {
$events = $this->parse($test);
$this->assertEquals(3, $events->depth());
// Should have triggered an error.
$this->assertEventError($events->get(0));
// Should have tried to parse anyway.
$this->assertEventEquals('comment', $result, $events->get(1));
}
}
public function testComment() {
$good = array(
'' => 'easy',
'' => ' 1 > 0 ',
'' => ' --$i ',
'' => '--$i',
'' => ' 1 > 0 ',
"" => "\nHello World.\na",
'' => ' ' => '',
'' => '',
'' => '',
);
foreach ($good as $test => $expects) {
$events = $this->parse($test);
$this->assertEventEquals('startTag', 'script', $events->get(0));
$this->assertEventEquals('text', $expects, $events->get(1));
$this->assertEventEquals('endTag', 'script', $events->get(2));
}
$bad = array(
' '&Hello world' => 'Hello world',
);
foreach ($bad as $test => $expects) {
$events = $this->parse($test);
$this->assertEquals(4, $events->depth(), "Counting events for '$test': " . print_r($events, TRUE));
$this->assertEventEquals('startTag', 'script', $events->get(0));
$this->assertEventError($events->get(1));
$this->assertEventEquals('text', $expects, $events->get(2));
}
}
public function testText() {
$events = $this->parse('a
b');
$this->assertEquals(4, $events->depth(), "Events: " . print_r($events, TRUE));
$this->assertEventEquals('text', 'a', $events->get(0));
$this->assertEventEquals('startTag', 'br', $events->get(1));
$this->assertEventEquals('text', 'b', $events->get(2));
$events = $this->parse('Test');
$this->assertEquals(4, $events->depth(), "Events: " . print_r($events, TRUE));
$this->assertEventEquals('startTag', 'a', $events->get(0));
$this->assertEventEquals('text', 'Test', $events->get(1));
$this->assertEventEquals('endTag', 'a', $events->get(2));
$events = $this->parse('ab');
$this->assertEquals(4, $events->depth(), "Events: " . print_r($events, TRUE));
$this->assertEventEquals('text', 'a', $events->get(0));
$this->assertEventEquals('cdata', 'test', $events->get(1));
$this->assertEventEquals('text', 'b', $events->get(2));
$events = $this->parse('ab');
$this->assertEquals(4, $events->depth(), "Events: " . print_r($events, TRUE));
$this->assertEventEquals('text', 'a', $events->get(0));
$this->assertEventEquals('comment', 'test', $events->get(1));
$this->assertEventEquals('text', 'b', $events->get(2));
$events = $this->parse('a&b');
$this->assertEquals(2, $events->depth(), "Events: " . print_r($events, TRUE));
$this->assertEventEquals('text', 'a&b', $events->get(0));
}
// ================================================================
// Utility functions.
// ================================================================
protected function createTokenizer($string, $debug = FALSE) {
$eventHandler = new EventStack();
$stream = new StringInputStream($string);
$scanner = new Scanner($stream);
$scanner->debug = $debug;
return array(
new Tokenizer($scanner, $eventHandler),
$eventHandler,
);
}
public function parse($string, $debug = FALSE) {
list($tok, $events) = $this->createTokenizer($string, $debug);
$tok->parse();
return $events;
}
}