You are here

public function TokenizerTest::testTagAttributes in Zircon Profile 8

Same name and namespace in other branches
  1. 8.0 vendor/masterminds/html5/test/HTML5/Parser/TokenizerTest.php \Masterminds\HTML5\Tests\Parser\TokenizerTest::testTagAttributes()

@depends testCharacterReference

File

vendor/masterminds/html5/test/HTML5/Parser/TokenizerTest.php, line 572

Class

TokenizerTest

Namespace

Masterminds\HTML5\Tests\Parser

Code

public function testTagAttributes() {

  // Opening tags.
  $good = array(
    '<foo bar="baz">' => array(
      'foo',
      array(
        'bar' => 'baz',
      ),
      false,
    ),
    '<foo bar=" baz ">' => array(
      'foo',
      array(
        'bar' => ' baz ',
      ),
      false,
    ),
    "<foo bar=\"\nbaz\n\">" => array(
      'foo',
      array(
        'bar' => "\nbaz\n",
      ),
      false,
    ),
    "<foo bar='baz'>" => array(
      'foo',
      array(
        'bar' => 'baz',
      ),
      false,
    ),
    '<foo bar="A full sentence.">' => array(
      'foo',
      array(
        'bar' => 'A full sentence.',
      ),
      false,
    ),
    "<foo a='1' b=\"2\">" => array(
      'foo',
      array(
        'a' => '1',
        'b' => '2',
      ),
      false,
    ),
    "<foo ns:bar='baz'>" => array(
      'foo',
      array(
        'ns:bar' => 'baz',
      ),
      false,
    ),
    "<foo a='blue&amp;red'>" => array(
      'foo',
      array(
        'a' => 'blue&red',
      ),
      false,
    ),
    "<foo a='blue&&amp;red'>" => array(
      'foo',
      array(
        'a' => 'blue&&red',
      ),
      false,
    ),
    "<foo\nbar='baz'\n>" => array(
      'foo',
      array(
        'bar' => 'baz',
      ),
      false,
    ),
    '<doe a deer>' => array(
      'doe',
      array(
        'a' => null,
        'deer' => null,
      ),
      false,
    ),
    '<foo bar=baz>' => array(
      'foo',
      array(
        'bar' => 'baz',
      ),
      false,
    ),
    // Updated for 8.1.2.3
    '<foo    bar   =   "baz"      >' => array(
      'foo',
      array(
        'bar' => 'baz',
      ),
      false,
    ),
    // The spec allows an unquoted value '/'. This will not be a closing
    // tag.
    '<foo bar=/>' => array(
      'foo',
      array(
        'bar' => '/',
      ),
      false,
    ),
    '<foo bar=baz/>' => array(
      'foo',
      array(
        'bar' => 'baz/',
      ),
      false,
    ),
  );
  $this
    ->isAllGood('startTag', 2, $good);

  // Self-closing tags.
  $withEnd = array(
    '<foo bar="baz"/>' => array(
      'foo',
      array(
        'bar' => 'baz',
      ),
      true,
    ),
    '<foo BAR="baz"/>' => array(
      'foo',
      array(
        'bar' => 'baz',
      ),
      true,
    ),
    '<foo BAR="BAZ"/>' => array(
      'foo',
      array(
        'bar' => 'BAZ',
      ),
      true,
    ),
    "<foo a='1' b=\"2\" c=3 d/>" => array(
      'foo',
      array(
        'a' => '1',
        'b' => '2',
        'c' => '3',
        'd' => null,
      ),
      true,
    ),
  );
  $this
    ->isAllGood('startTag', 3, $withEnd);

  // Cause a parse error.
  $bad = array(
    // This will emit an entity lookup failure for &red.
    "<foo a='blue&red'>" => array(
      'foo',
      array(
        'a' => 'blue&red',
      ),
      false,
    ),
    "<foo a='blue&&amp;&red'>" => array(
      'foo',
      array(
        'a' => 'blue&&&red',
      ),
      false,
    ),
    '<foo bar=>' => array(
      'foo',
      array(
        'bar' => null,
      ),
      false,
    ),
    '<foo bar="oh' => array(
      'foo',
      array(
        'bar' => 'oh',
      ),
      false,
    ),
    '<foo bar=oh">' => array(
      'foo',
      array(
        'bar' => 'oh"',
      ),
      false,
    ),
    // these attributes are ignored because of current implementation
    // of method "DOMElement::setAttribute"
    // see issue #23: https://github.com/Masterminds/html5-php/issues/23
    '<foo b"="baz">' => array(
      'foo',
      array(),
      false,
    ),
    '<foo 2abc="baz">' => array(
      'foo',
      array(),
      false,
    ),
    '<foo ?="baz">' => array(
      'foo',
      array(),
      false,
    ),
    '<foo foo?bar="baz">' => array(
      'foo',
      array(),
      false,
    ),
  );
  foreach ($bad as $test => $expects) {
    $events = $this
      ->parse($test);
    $this
      ->assertEquals(3, $events
      ->depth(), "Counting events for '{$test}': " . print_r($events, true));
    $this
      ->assertEventError($events
      ->get(0));
    $this
      ->assertEventEquals('startTag', $expects, $events
      ->get(1));
  }

  // Cause multiple parse errors.
  $reallyBad = array(
    '<foo ="bar">' => array(
      'foo',
      array(
        '=' => null,
        '"bar"' => null,
      ),
      false,
    ),
    '<foo////>' => array(
      'foo',
      array(),
      true,
    ),
    // character "&" in unquoted attribute shouldn't cause an infinite loop
    '<foo bar=index.php?str=1&amp;id=29>' => array(
      'foo',
      array(
        'bar' => 'index.php?str=1&id=29',
      ),
      false,
    ),
  );
  foreach ($reallyBad as $test => $expects) {
    $events = $this
      ->parse($test);

    // fprintf(STDOUT, $test . print_r($events, true));
    $this
      ->assertEventError($events
      ->get(0));
    $this
      ->assertEventError($events
      ->get(1));

    // $this->assertEventEquals('startTag', $expects, $events->get(1));
  }

  // Regression: Malformed elements should be detected.
  // '<foo baz="1" <bar></foo>' => array('foo', array('baz' => '1'), false),
  $events = $this
    ->parse('<foo baz="1" <bar></foo>');
  $this
    ->assertEventError($events
    ->get(0));
  $this
    ->assertEventEquals('startTag', array(
    'foo',
    array(
      'baz' => '1',
    ),
    false,
  ), $events
    ->get(1));
  $this
    ->assertEventEquals('startTag', array(
    'bar',
    array(),
    false,
  ), $events
    ->get(2));
  $this
    ->assertEventEquals('endTag', array(
    'foo',
  ), $events
    ->get(3));
}