[ Index ]

PHP Cross Reference of Limb3

title

Body

[close]

/wact/tests/cases/compiler/parser/ -> WactHTMLParserTest.class.php (source)

   1  <?php
   2  /*
   3   * Limb PHP Framework
   4   *
   5   * @link http://limb-project.com 
   6   * @copyright  Copyright &copy; 2004-2007 BIT(http://bit-creative.com)
   7   * @license    LGPL http://www.gnu.org/copyleft/lesser.html 
   8   */
   9  
  10  require_once('limb/wact/src/compiler/templatecompiler.inc.php');
  11  
  12  Mock::generate('WactParserListener', 'MockWactParserListener');
  13  
  14  class WactHTMLParserListenerStub implements WactHTMLParserListener
  15  {
  16    public $events = array();
  17  
  18    function characters($text, $location)
  19    {
  20      $this->events[] = array('characters', $text, $location);
  21    }
  22  
  23    function startTag($tag, $attributes, $location)
  24    {
  25      $this->events[] = array('startTag', $tag, $attributes, $location);
  26    }
  27  
  28    function endTag($tag, $location)
  29    {
  30      $this->events[] = array('endTag', $tag, $location);
  31    }
  32  
  33    function emptyTag($tag, $attributes, $location)
  34    {
  35      $this->events[] = array('emptyTag', $tag, $attributes, $location);
  36    }
  37  
  38    function instruction($type, $code, $location)
  39    {
  40      $this->events[] = array('instruction', $type, $code, $location);
  41    }
  42  }
  43  
  44  class WactHTMLParserTest extends UnitTestCase
  45  {
  46    protected $parser;
  47    protected $listener;
  48  
  49    function setUp()
  50    {
  51      $this->listener = new WactHTMLParserListenerStub();
  52      $this->parser = new WactHTMLParser($this->listener);
  53      $this->file_name = 'my_file';
  54    }
  55  
  56    protected function _createLocation($line = 1)
  57    {
  58      return new WactSourceLocation('my_file', $line);
  59    }
  60  
  61    function testEmpty()
  62    {
  63      $this->parser->parse('', $this->file_name);
  64      $this->assertEqual($this->listener->events, array());
  65    }
  66  
  67    function testSimpleDataIsCharacters()
  68    {
  69      $location = $this->_createLocation();
  70      $this->parser->parse('stuff', $this->file_name);
  71  
  72      $this->checkEventsCount(1);
  73      $this->checkCharactersEvent(0, 'stuff', $location);
  74    }
  75  
  76    function testPreservingWhiteSpace()
  77    {
  78      $this->parser->parse(" stuff\t\r\n ", $this->file_name);
  79      $this->checkEventsCount(1);
  80      $this->checkCharactersEvent(0, " stuff\t\r\n ");
  81    }
  82  
  83    function testTagWithNoContentNoAttributes()
  84    {
  85      $location = $this->_createLocation();
  86  
  87      $this->parser->parse('<tag></tag>', $this->file_name);
  88  
  89      $this->checkEventsCount(2);
  90      $this->checkStartTagEvent(0, "tag", array(), $location);
  91      $this->checkEndTagEvent(1, "tag", $location);
  92    }
  93  
  94    function testEmptyTag()
  95    {
  96      $location = $this->_createLocation();
  97  
  98      $this->parser->parse('<br/>', $this->file_name);
  99  
 100      $this->checkEventsCount(1);
 101      $this->checkEmptyTagEvent(0, "br", array(), $location);
 102    }
 103  
 104    function testTagWithContent()
 105    {
 106      $this->parser->parse('<tag>stuff</tag>', $this->file_name);
 107  
 108      $this->checkEventsCount(3);
 109      $this->checkStartTagEvent(0, "tag", array());
 110      $this->checkCharactersEvent(1, "stuff");
 111      $this->checkEndTagEvent(2, "tag");
 112    }
 113  
 114    function testEmptyComment()
 115    {
 116      $this->parser->parse('<!---->', $this->file_name);
 117  
 118      $this->checkEventsCount(1);
 119      $this->checkCharactersEvent(0, "<!---->");
 120    }
 121  
 122    function testTruncatedComment()
 123    {
 124      $location = $this->_createLocation();
 125      $this->parser->parse('stuff<!--', $this->file_name);
 126      $this->checkEventsCount(2);
 127      $this->checkCharactersEvent(0, 'stuff', $location);
 128      $this->checkCharactersEvent(1, '<!--', $location);
 129    }
 130  
 131    function testTruncatedCommentNoClose()
 132    {
 133      $location = $this->_createLocation();
 134      $this->parser->parse('stuff<!-- blah', $this->file_name);
 135      $this->checkEventsCount(2);
 136      $this->checkCharactersEvent(0, 'stuff', $location);
 137      $this->checkCharactersEvent(1, '<!-- blah', $location);
 138    }
 139  
 140    function testMalformedComment()
 141    {
 142      $location = $this->_createLocation();
 143      $this->parser->parse('<!--x->', $this->file_name);
 144      $this->checkEventsCount(1);
 145      $this->checkCharactersEvent(0, '<!--x->', $location);
 146    }
 147  
 148    function testAttributes()
 149    {
 150      $this->parser->parse('<tag a="A" b=\'B\' c = "C">', $this->file_name);
 151      $this->checkEventsCount(1);
 152      $this->checkStartTagEvent(0, "tag", array("a" => "A", "b" => "B", "c" => "C"));
 153    }
 154  
 155    function testEmptyAttributes()
 156    {
 157      $this->parser->parse('<tag a b c>', $this->file_name);
 158      $this->checkEventsCount(1);
 159      $this->checkStartTagEvent(0, "tag", array("a" => NULL, "b" => NULL, "c" => NULL));
 160    }
 161  
 162    function testNastyAttributes()
 163    {
 164      $this->parser->parse("<tag a=\"&%$'?<>\" b='\r\n\t\"' c = ''>", $this->file_name);
 165      $this->checkEventsCount(1);
 166      $this->checkStartTagEvent(0, "tag", array("a" => "&%$'?<>",
 167                                                "b" => "\r\n\t\"",
 168                                                "c" => ""));
 169    }
 170  
 171    function testAttributesPadding()
 172    {
 173      $this->parser->parse("<tag\ta=\"A\"\rb='B'\nc = \"C\"\n>", $this->file_name);
 174      $this->checkEventsCount(1);
 175      $this->checkStartTagEvent(0, "tag", array("a" => "A", "b" => "B", "c" => "C"));
 176    }
 177  
 178    function testTagWithDoubleQuotedAttribute()
 179    {
 180      $this->parser->parse('<tag attribute="\'">', $this->file_name);
 181  
 182      $this->checkEventsCount(1);
 183      $this->checkStartTagEvent(0, "tag", array('attribute' => '\''));
 184    }
 185  
 186    function testTagWithSingleQuotedAttribute()
 187    {
 188      $this->parser->parse('<tag attribute=\'"\'>', $this->file_name);
 189      $this->checkEventsCount(1);
 190      $this->checkStartTagEvent(0, "tag", array('attribute' => '"'));
 191    }
 192  
 193    function testTagNestedSingleQuoteAttributeThrowsException()
 194    {
 195      try
 196      {
 197        $this->parser->parse('<tag attribute=\'\'\'>', $this->file_name);
 198        $this->assertTrue(false);
 199      }
 200      catch(WactException $e)
 201      {
 202        $this->assertWantedPattern('/Invalid tag attribute syntax/', $e->getMessage());
 203        $this->assertEqual($e->getParam('file'), $this->file_name);
 204        $this->assertEqual($e->getParam('line'), 1);
 205      }
 206    }
 207  
 208    function testTagNestedDoubleQuoteAttributeThrowsException()
 209    {
 210      try
 211      {
 212        $this->parser->parse('<tag attribute=""">', $this->file_name);
 213        $this->assertTrue(false);
 214      }
 215      catch(WactException $e)
 216      {
 217        $this->assertWantedPattern('/Invalid tag attribute syntax/', $e->getMessage());
 218        $this->assertEqual($e->getParam('file'), $this->file_name);
 219        $this->assertEqual($e->getParam('line'), 1);
 220      }
 221    }
 222  
 223    function testTagNoSpaceAfterAttributeThrowsException()
 224    {
 225      try
 226      {
 227        $this->parser->parse('<tag attribute="test"extra>', $this->file_name);
 228        $this->assertTrue(false);
 229      }
 230      catch(WactException $e)
 231      {
 232        $this->assertWantedPattern('/Invalid tag attribute syntax/', $e->getMessage());
 233        $this->assertEqual($e->getParam('file'), $this->file_name);
 234        $this->assertEqual($e->getParam('line'), 1);
 235      }
 236    }
 237  
 238    function testOpenTagMalformedCloseThrowsException()
 239    {
 240      try
 241      {
 242        $this->parser->parse('stuff<tag attribute=\'value\'/morestuff', $this->file_name);
 243        $this->assertTrue(false);
 244      }
 245      catch(WactException $e)
 246      {
 247        $this->assertWantedPattern('/Invalid tag syntax/', $e->getMessage());
 248        $this->assertEqual($e->getParam('file'), $this->file_name);
 249        $this->assertEqual($e->getParam('line'), 1);
 250      }
 251    }
 252  
 253    function testOpenTagMalformedCloseThrowsException2()
 254    {
 255      try
 256      {
 257        $this->parser->parse('stuff<tag attribute=\'value\'/morestuff>', $this->file_name);
 258        $this->assertTrue(false);
 259      }
 260      catch(WactException $e)
 261      {
 262        $this->assertWantedPattern('/Invalid tag syntax/', $e->getMessage());
 263        $this->assertEqual($e->getParam('file'), $this->file_name);
 264        $this->assertEqual($e->getParam('line'), 1);
 265      }
 266    }
 267  
 268    function testElementWithPreContent()
 269    {
 270      $this->parser->parse('stuff<br>', $this->file_name);
 271      $this->checkEventsCount(2);
 272      $this->checkCharactersEvent(0, "stuff");
 273      $this->checkStartTagEvent(1, "br", array());
 274    }
 275  
 276    function testElementWithPostContent()
 277    {
 278      $this->parser->parse('<br>stuff', $this->file_name);
 279      $this->checkEventsCount(2);
 280      $this->checkStartTagEvent(0, "br", array());
 281      $this->checkCharactersEvent(1, "stuff");
 282    }
 283  
 284    function testExpressionAfterTag()
 285    {
 286      $this->parser->parse('<br/>{$str|clip:5}', $this->file_name);
 287      $this->checkEventsCount(2);
 288      $this->checkEmptyTagEvent(0, "br", array());
 289      $this->checkCharactersEvent(1, '{$str|clip:5}');
 290    }
 291  
 292    function testExpressionAfterTagWithArguments()
 293    {
 294      $this->parser->parse('<core:set str="abcdefgh" />{$str|clip:5}', $this->file_name);
 295      $this->checkEventsCount(2);
 296      $this->checkEmptyTagEvent(0, "core:set", array('str' => 'abcdefgh'));
 297      $this->checkCharactersEvent(1, '{$str|clip:5}');
 298    }
 299  
 300    function testMismatchedTags()
 301    {
 302      $this->parser->parse('<b><i>stuff</b></i>', $this->file_name);
 303      $this->checkEventsCount(5);
 304      $this->checkStartTagEvent(0, "b", array());
 305      $this->checkStartTagEvent(1, "i", array());
 306      $this->checkCharactersEvent(2, "stuff");
 307      $this->checkEndTagEvent(3, "b", array());
 308      $this->checkEndTagEvent(4, "i", array());
 309    }
 310  
 311    function testScriptTagWithTagsInsideGeneratedCode()
 312    {
 313      $this->parser->parse('<script language="Javascript">document.write(\'<B>Test</B>\');</script>');
 314      $this->checkEventsCount(7);
 315      $this->checkStartTagEvent(0, "script", array('language' => "Javascript"));
 316      $this->checkCharactersEvent(1, 'document.write(\'');
 317      $this->checkStartTagEvent(2, "B", array());
 318      $this->checkCharactersEvent(3, 'Test');
 319      $this->checkEndTagEvent(4, "B");
 320      $this->checkCharactersEvent(5, '\');');
 321      $this->checkEndTagEvent(6, "script");
 322    }
 323  
 324    function testIgnoreTagsInsideCommentsBlock()
 325    {
 326      $this->parser->parse('<script language="Javascript"><!-- document.write(\'<B>Test</B>\'); --></script>');
 327      $this->checkEventsCount(3);
 328      $this->checkStartTagEvent(0, "script", array('language' => "Javascript"));
 329      $this->checkCharactersEvent(1, '<!-- document.write(\'<B>Test</B>\'); -->');
 330      $this->checkEndTagEvent(2, "script");
 331    }
 332  
 333    function testTruncatedOpenTagChar()
 334    {
 335      $location = $this->_createLocation();
 336      $this->parser->parse('stuff<a', $this->file_name);
 337      $this->checkEventsCount(2);
 338      $this->checkCharactersEvent(0, 'stuff', $location);
 339      $this->checkCharactersEvent(1, '<a', $location);
 340    }
 341  
 342    function testTruncatedOpenTag()
 343    {
 344      $location = $this->_createLocation();
 345      $this->parser->parse('stuff<tag', $this->file_name);
 346      $this->checkCharactersEvent(0, 'stuff', $location);
 347      $this->checkCharactersEvent(1, '<tag', $location);
 348    }
 349  
 350    function testTruncatedOpenTagWithSpace()
 351    {
 352      $location = $this->_createLocation();
 353      $this->parser->parse('stuff<tag ', $this->file_name);
 354      $this->checkCharactersEvent(0, 'stuff', $location);
 355      $this->checkCharactersEvent(1, '<tag ', $location);
 356    }
 357  
 358    function testTruncatedOpenTagMinimizedAttribute()
 359    {
 360      $location = $this->_createLocation();
 361      $this->parser->parse('stuff<tag attribute', $this->file_name);
 362      $this->checkCharactersEvent(0, 'stuff', $location);
 363      $this->checkCharactersEvent(1, '<tag attribute', $location);
 364    }
 365  
 366    function testTruncatedOpenTagMinimizedAttributeSpace()
 367    {
 368      $location = $this->_createLocation();
 369      $this->parser->parse('stuff<tag attribute ', $this->file_name);
 370      $this->checkCharactersEvent(0, 'stuff', $location);
 371      $this->checkCharactersEvent(1, '<tag attribute ', $location);
 372    }
 373  
 374    function testTruncatedOpenTagAttribute()
 375    {
 376      $location = $this->_createLocation();
 377      $this->parser->parse('stuff<tag attribute=', $this->file_name);
 378      $this->checkCharactersEvent(0, 'stuff', $location);
 379      $this->checkCharactersEvent(1, '<tag attribute=', $location);
 380    }
 381  
 382    function testTruncatedOpenTagAttributeAndSpace()
 383    {
 384      $location = $this->_createLocation();
 385      $this->parser->parse('stuff<tag attribute= ', $this->file_name);
 386      $this->checkCharactersEvent(0, 'stuff', $location);
 387      $this->checkCharactersEvent(1, '<tag attribute= ', $location);
 388    }
<