appendChild($d->createElement('html')); $d->documentElement->appendChild($d->createElement('body')); $div = $d->body->appendChild($d->createElement('div')); $ook = $d->body->insertBefore($d->createTextNode('ook'), $div); $this->assertSame('ook
', (string)$d->body); $t = $d->body->insertBefore($d->createElement('template'), $ook); $this->assertSame('ook
', (string)$d->body); $this->assertTrue(ElementMap::has($t)); } public function providePreInsertionValidationFailures(): iterable { return [ [ function() { $d = new Document(); $d->appendChild($d->createElement('html')); $b = $d->documentElement->appendChild($d->createElement('body')); $b->appendChild($d->documentElement); } ], [ function() { $d = new Document(); $d->appendChild($d->createElement('html')); $b = $d->documentElement->appendChild($d->createElement('body')); $t = $b->appendChild($d->createElement('template')); $t->content->appendChild($b); } ], [ function() { $d = new Document(); $d->appendChild($d->createElement('html')); $b = $d->documentElement->appendChild($d->createElement('body')); $d->insertBefore($d->createElement('fail'), $b); }, DOMException::NOT_FOUND ], [ function() { $d = new Document(); $df = $d->createDocumentFragment(); $df->appendChild($d->createElement('html')); $df->appendChild($d->createTextNode(' ')); $d->appendChild($df); } ], [ function() { $d = new Document(); $d->appendChild($d); } ], [ function() { $d = new Document(); $d->appendChild($d->implementation->createDocumentType('html')); $d->appendChild($d->implementation->createDocumentType('html')); } ], [ function() { $d = new Document(); $d->appendChild($d->createElement('html')); $d->appendChild($d->implementation->createDocumentType('html')); } ], [ function() { $d = new Document(); $d->appendChild($d->createElement('html')); $c = $d->appendChild($d->createComment('ook')); $d->insertBefore($d->implementation->createDocumentType('html'), $c); } ], [ function() { $d = new Document(); $d->appendChild($d->createElement('html')); $d->documentElement->insertBefore($d->implementation->createDocumentType('html')); } ], [ function() { $d = new Document(); $d->appendChild($d->createElement('html')); $d->documentElement->insertBefore($d->implementation->createDocumentType('html')); } ], [ function() { $d = new Document(); $dt = $d->appendChild($d->implementation->createDocumentType('html')); $df = $d->createDocumentFragment(); $df->appendChild($d->createElement('html')); $d->insertBefore($df, $dt); } ], [ function() { $d = new Document(); $c = $d->appendChild($d->createComment('OOK')); $d->appendChild($d->implementation->createDocumentType('html')); $df = $d->createDocumentFragment(); $df->appendChild($d->createElement('html')); $d->insertBefore($df, $c); } ], [ function() { $d = new Document(); $dt = $d->appendChild($d->implementation->createDocumentType('html')); $d->insertBefore($d->createElement('html'), $dt); } ], [ function() { $d = new Document(); $c = $d->appendChild($d->createComment('OOK')); $d->appendChild($d->implementation->createDocumentType('html')); $d->insertBefore($d->createElement('html'), $c); } ], [ function() { $d = new Document(); $d->appendChild($d->createElement('html')); $d->appendChild($d->createElement('body')); } ] ]; } /** * @dataProvider providePreInsertionValidationFailures * @covers \MensBeam\HTML\DOM\DOMException::__construct * @covers \MensBeam\HTML\DOM\NodeTrait::getRootNode * @covers \MensBeam\HTML\DOM\ParentNode::preInsertionValidity */ public function testPreInsertionValidationFailures(\Closure $closure, int $errorCode = DOMException::HIERARCHY_REQUEST_ERROR): void { $this->expectException(DOMException::class); $this->expectExceptionCode($errorCode); $closure(); } /** @covers \MensBeam\HTML\DOM\ParentNode::__get_children */ public function testPropertyGetChildren(): void { $d = new Document(); $d->appendChild($d->createElement('html')); $d->documentElement->appendChild($d->createElement('body')); $this->assertSame(1, $d->documentElement->children->length); } /** * @covers \MensBeam\HTML\DOM\ParentNode::querySelector * @covers \MensBeam\HTML\DOM\ParentNode::querySelectorAll * @covers \MensBeam\HTML\DOM\ParentNode::scopeMatchSelector * @covers \MensBeam\HTML\DOM\NodeList::__construct * @covers \MensBeam\HTML\DOM\NodeList::item */ public function testQuerySelector(): void { $d = new Document('
ook
eek
'); $div = $d->body->querySelector('div'); $this->assertSame('div', $div->nodeName); $this->assertNull($d->querySelector('body::before')); $divs = $d->body->querySelectorAll('div'); $this->assertEquals(2, $divs->length); $this->assertSame('eek', $divs->item(1)->getAttribute('id')); $this->assertNull($d->querySelector('.ook')); $this->assertEquals(0, $d->querySelectorAll('body::before')->length); } /** * @covers \MensBeam\HTML\DOM\ParentNode::querySelector * @covers \MensBeam\HTML\DOM\ParentNode::querySelectorAll * @covers \MensBeam\HTML\DOM\ParentNode::scopeMatchSelector */ public function testQuerySelectorFailure(): void { $this->expectException(DOMException::class); $this->expectExceptionCode(DOMException::SYNTAX_ERROR); $d = new Document(); $d->querySelector('ook?'); } /** @covers \MensBeam\HTML\DOM\ParentNode::replaceChild */ public function testReplaceChild(): void { $d = new Document(); $d->appendChild($d->createElement('html')); $d->documentElement->appendChild($d->createElement('body')); $div = $d->body->appendChild($d->createElement('div')); $ook = $d->body->replaceChild($d->createTextNode('ook'), $div); $this->assertSame('ook', (string)$d->body); $t = $d->body->replaceChild($d->createElement('template'), $ook); $this->assertSame('', (string)$d->body); $this->assertTrue(ElementMap::has($t)); $d->body->replaceChild($d->createElement('br'), $t); $this->assertSame('
', (string)$d->body); $this->assertFalse(ElementMap::has($t)); } /** @covers \MensBeam\HTML\DOM\ParentNode::replaceChildren */ public function testReplaceChildren(): void { $d = new Document(); $d->appendChild($d->createElement('html')); $d->documentElement->appendChild($d->createElement('body')); $div = $d->body->appendChild($d->createElement('div')); $ook = $d->body->appendChild($d->createTextNode('ook'), $d->body->appendChild($d->createElement('div'))); $d->body->replaceChildren($d->createElement('br'), 'ook', $d->createElement('span'), 'eek'); $this->assertSame('
ookeek', (string)$d->body); $d->body->replaceChildren('ook'); $this->assertSame('ook', (string)$d->body); } /** @covers \MensBeam\HTML\DOM\ParentNode::walk */ public function testWalk(): void { // Test removal of elements when walking $d = new Document(); $d->appendChild($d->createElement('html')); $d->documentElement->appendChild($d->createElement('body')); $d->body->innerHTML = 'OOOK'; $spans = $d->body->walk(function($n) { return ($n instanceof Element && $n->nodeName === 'span'); }); foreach ($spans as $s) { if ($s->getAttribute('class') === 'three') { $s->parentNode->removeChild($s); } } $this->assertSame('OOK', (string)$d->body); // Test walking through templates' content $d = new Document(); $d->appendChild($d->createElement('html')); $d->documentElement->appendChild($d->createElement('body')); $t = $d->body->appendChild($d->createElement('template')); $t->content->appendChild($d->createElement('ook')); $this->assertSame('ook', $d->body->walk(function($n) { return ($n instanceof Element && $n->nodeName === 'ook'); })->current()->nodeName); } public function provideWalkFailures(): iterable { $d = new Document(); $d->appendChild($d->createElement('html')); $d->documentElement->appendChild($d->createElement('body')); $d->body->innerHTML = '

Ook

Eek

Ook eek, ook?

'; return [ [ function() use ($d) { $d->body->walk(function($n) { return 'ook'; })->current(); } ], [ function() use ($d) { $d->body->walk(function($n) { return new \DateTime(); })->current(); } ] ]; } /** * @dataProvider provideWalkFailures * @covers \MensBeam\HTML\DOM\DOMException::__construct * @covers \MensBeam\HTML\DOM\ParentNode::walk */ public function testWalkFailures(\Closure $closure): void { $this->expectException(Exception::class); $this->expectExceptionCode(Exception::CLOSURE_RETURN_TYPE_ERROR); $closure(); } }