assertEquals($type, $event['name'], "Event $type for " . print_r($event, true));
if (is_array($expects)) {
$this->assertEquals($expects, $event['data'], "Event $type should equal " . print_r($expects, true) . ": " . 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',
"" => "\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));
}
// Testing case sensitivity
$events = $this->parse('
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('
0
1
'); $this->assertEquals(7, $events->depth(), "Events: " . print_r($events, true)); $this->assertEventEquals('startTag', 'p', $events->get(0)); $this->assertEventEquals('text', '0', $events->get(1)); $this->assertEventEquals('endTag', 'p', $events->get(2)); $this->assertEventEquals('startTag', 'p', $events->get(3)); $this->assertEventEquals('text', '1', $events->get(4)); $this->assertEventEquals('endTag', 'p', $events->get(5)); $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)); $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; } }