Browse Source

Started adding test cases for Node::replaceChild

wrapper-classes
Dustin Wilson 3 years ago
parent
commit
80135ef2a6
  1. 22
      lib/InnerNode/Document.php
  2. 38
      lib/Node.php
  3. 228
      tests/cases/TestNode.php

22
lib/InnerNode/Document.php

@ -49,19 +49,7 @@ class Document extends \DOMDocument {
} }
public function getInnerNode(WrapperNode $node = null): ?\DOMNode { public function getInnerNode(WrapperNode $node): ?\DOMNode {
if ($node === null) {
return null;
}
if ($node === $this) {
return $this;
}
if ($node instanceof \DOMDocument) {
throw new DOMException(DOMException::WRONG_DOCUMENT);
}
return $this->nodeMap->get($node); return $this->nodeMap->get($node);
} }
@ -88,8 +76,6 @@ class Document extends \DOMDocument {
$className = 'CDATASection'; $className = 'CDATASection';
} elseif ($node instanceof \DOMComment) { } elseif ($node instanceof \DOMComment) {
$className = 'Comment'; $className = 'Comment';
} elseif ($node instanceof \DOMDocument) {
$className = ($this->wrapperNode instanceof WrapperXMLDocument) ? 'XMLDocument' : 'Document';
} elseif ($node instanceof \DOMDocumentFragment) { } elseif ($node instanceof \DOMDocumentFragment) {
$className = 'DocumentFragment'; $className = 'DocumentFragment';
} elseif ($node instanceof \DOMDocumentType) { } elseif ($node instanceof \DOMDocumentType) {
@ -123,11 +109,7 @@ class Document extends \DOMDocument {
Reflection::setProtectedProperties($wrapperNode, [ '_ownerDocument' => $this->_wrapperNode ]); Reflection::setProtectedProperties($wrapperNode, [ '_ownerDocument' => $this->_wrapperNode ]);
} }
// Don't put documents into the node map cache to prevent circular references. $this->nodeMap->set($wrapperNode, $node);
if ($className !== 'Document') {
$this->nodeMap->set($wrapperNode, $node);
}
return $wrapperNode; return $wrapperNode;
} }
} }

38
lib/Node.php

@ -560,6 +560,11 @@ abstract class Node {
} }
public function replaceChild(Node $node, Node $child): Node { public function replaceChild(Node $node, Node $child): Node {
$wrapperNode = $node;
$node = $this->getInnerNode($node);
$child = $this->getInnerNode($child);
$inner = $this->innerNode;
# The replaceChild(node, child) method steps are to return the result of # The replaceChild(node, child) method steps are to return the result of
# replacing child with node within this. # replacing child with node within this.
// PHP's DOM has some issues due to not checking for some edge cases the DOM // PHP's DOM has some issues due to not checking for some edge cases the DOM
@ -570,46 +575,49 @@ abstract class Node {
# #
# 1. If parent is not a Document, DocumentFragment, or Element node, then throw # 1. If parent is not a Document, DocumentFragment, or Element node, then throw
# a "HierarchyRequestError" DOMException. # a "HierarchyRequestError" DOMException.
if (!$this instanceof Document && !$this instanceof DocumentFragment && !$this instanceof Element) { if (!$inner instanceof InnerDocument && !$inner instanceof \DOMDocumentFragment && !$inner instanceof \DOMElement) {
throw new DOMException(DOMException::HIERARCHY_REQUEST_ERROR); throw new DOMException(DOMException::HIERARCHY_REQUEST_ERROR);
} }
# 2. If node is a host-including inclusive ancestor of parent, then throw a # 2. If node is a host-including inclusive ancestor of parent, then throw a
# "HierarchyRequestError" DOMException. # "HierarchyRequestError" DOMException.
if ($node->contains($this)) { // The specification makes no mention of checking to see if child is a
// host-including inclusive ancestor of parent or if child is a host-including
// inclusive ancestor of node, but it should. All browsers check for this.
if ($this->containsInner($node, $inner) || $this->containsInner($node, $child)) {
throw new DOMException(DOMException::HIERARCHY_REQUEST_ERROR); throw new DOMException(DOMException::HIERARCHY_REQUEST_ERROR);
} }
# 3. If child’s parent is not parent, then throw a "NotFoundError" DOMException. # 3. If child’s parent is not parent, then throw a "NotFoundError" DOMException.
if ($child->parentNode !== $this) { if ($child->parentNode !== $inner) {
throw new DOMException(DOMException::NOT_FOUND); throw new DOMException(DOMException::NOT_FOUND);
} }
# 4. If node is not a DocumentFragment, DocumentType, Element, or CharacterData # 4. If node is not a DocumentFragment, DocumentType, Element, or CharacterData
# node, then throw a "HierarchyRequestError" DOMException. # node, then throw a "HierarchyRequestError" DOMException.
if (!$node instanceof DocumentFragment && !$node instanceof DocumentType && !$node instanceof Element && !$node instanceof CharacterData) { if (!$node instanceof \DOMDocumentFragment && !$node instanceof \DOMDocumentType && !$node instanceof \DOMElement && !$node instanceof \DOMCharacterData) {
throw new DOMException(DOMException::HIERARCHY_REQUEST_ERROR); throw new DOMException(DOMException::HIERARCHY_REQUEST_ERROR);
} }
# 5. If either node is a Text node and parent is a document, or node is a # 5. If either node is a Text node and parent is a document, or node is a
# doctype and parent is not a document, then throw a "HierarchyRequestError" # doctype and parent is not a document, then throw a "HierarchyRequestError"
# DOMException. # DOMException.
if (($node instanceof Text && $this instanceof Document) || ($node instanceof DocumentType && !$this instanceof Document)) { if (($node instanceof \DOMText && $inner instanceof InnerDocument) || ($node instanceof \DOMDocumentType && !$inner instanceof InnerDocument)) {
throw new DOMException(DOMException::HIERARCHY_REQUEST_ERROR); throw new DOMException(DOMException::HIERARCHY_REQUEST_ERROR);
} }
# 6. If parent is a document, and any of the statements below, switched on the # 6. If parent is a document, and any of the statements below, switched on the
# interface node implements, are true, then throw a "HierarchyRequestError". # interface node implements, are true, then throw a "HierarchyRequestError".
if ($this instanceof Document) { if ($inner instanceof InnerDocument) {
# ↪ DocumentFragment # ↪ DocumentFragment
# If node has more than one element child or has a Text node child. # If node has more than one element child or has a Text node child.
# #
# Otherwise, if node has one element child and either parent has an element # Otherwise, if node has one element child and either parent has an element
# child that is not child or a doctype is following child. # child that is not child or a doctype is following child.
if ($node instanceof DocumentFragment) { if ($node instanceof \DOMDocumentFragment) {
$nodeChildElementCount = $node->childElementCount; $nodeChildElementCount = $node->childElementCount;
if ($nodeChildElementCount > 1) { if ($nodeChildElementCount > 1) {
$n = $this->getInnerNode($node)->firstChild; $n = $node->firstChild;
do { do {
if ($n instanceof \DOMText) { if ($n instanceof \DOMText) {
throw new DOMException(DOMException::HIERARCHY_REQUEST_ERROR); throw new DOMException(DOMException::HIERARCHY_REQUEST_ERROR);
@ -617,7 +625,7 @@ abstract class Node {
} while ($n = $n->nextSibling); } while ($n = $n->nextSibling);
} elseif ($nodeChildElementCount === 1) { } elseif ($nodeChildElementCount === 1) {
$beforeChild = true; $beforeChild = true;
$n = $this->getInnerNode($node)->firstChild; $n = $node->firstChild;
do { do {
if (!$beforeChild && $n instanceof \DOMDocumentType) { if (!$beforeChild && $n instanceof \DOMDocumentType) {
throw new DOMException(DOMException::HIERARCHY_REQUEST_ERROR); throw new DOMException(DOMException::HIERARCHY_REQUEST_ERROR);
@ -635,9 +643,9 @@ abstract class Node {
# ↪ Element # ↪ Element
# parent has an element child that is not child or a doctype is following # parent has an element child that is not child or a doctype is following
# child. # child.
elseif ($node instanceof Element) { elseif ($node instanceof \DOMElement) {
$beforeChild = true; $beforeChild = true;
$n = $this->getInnerNode($node)->firstChild; $n = $node->firstChild;
do { do {
if (!$beforeChild && $n instanceof \DOMDocumentType) { if (!$beforeChild && $n instanceof \DOMDocumentType) {
throw new DOMException(DOMException::HIERARCHY_REQUEST_ERROR); throw new DOMException(DOMException::HIERARCHY_REQUEST_ERROR);
@ -654,9 +662,9 @@ abstract class Node {
# ↪ DocumentType # ↪ DocumentType
# parent has a doctype child that is not child, or an element is preceding # parent has a doctype child that is not child, or an element is preceding
# child. # child.
elseif ($node instanceof DocumentType) { elseif ($node instanceof \DOMDocumentType) {
$beforeChild = true; $beforeChild = true;
$n = $this->getInnerNode($node)->firstChild; $n = $node->firstChild;
do { do {
if (!$beforeChild && $n instanceof \DOMElement) { if (!$beforeChild && $n instanceof \DOMElement) {
throw new DOMException(DOMException::HIERARCHY_REQUEST_ERROR); throw new DOMException(DOMException::HIERARCHY_REQUEST_ERROR);
@ -672,8 +680,8 @@ abstract class Node {
} }
// PHP's DOM does fine with the rest of the steps. // PHP's DOM does fine with the rest of the steps.
$this->innerNode->replaceChild($this->getInnerNode($node), $this->getInnerNode($child)); $inner->replaceChild($node, $child);
return $node; return $wrapperNode;
} }

228
tests/cases/TestNode.php

@ -10,6 +10,7 @@ namespace MensBeam\HTML\DOM\TestCase;
use MensBeam\HTML\DOM\{ use MensBeam\HTML\DOM\{
Document, Document,
DOMException,
Node, Node,
XMLDocument XMLDocument
}; };
@ -39,6 +40,7 @@ class TestNode extends \PHPUnit\Framework\TestCase {
* @covers \MensBeam\HTML\DOM\Document::createElement * @covers \MensBeam\HTML\DOM\Document::createElement
* @covers \MensBeam\HTML\DOM\Document::createProcessingInstruction * @covers \MensBeam\HTML\DOM\Document::createProcessingInstruction
* @covers \MensBeam\HTML\DOM\Document::createTextNode * @covers \MensBeam\HTML\DOM\Document::createTextNode
* @covers \MensBeam\HTML\DOM\Document::load
* @covers \MensBeam\HTML\DOM\DocumentFragment::__construct * @covers \MensBeam\HTML\DOM\DocumentFragment::__construct
* @covers \MensBeam\HTML\DOM\DocumentType::__construct * @covers \MensBeam\HTML\DOM\DocumentType::__construct
* @covers \MensBeam\HTML\DOM\DocumentType::__get_name * @covers \MensBeam\HTML\DOM\DocumentType::__get_name
@ -57,6 +59,7 @@ class TestNode extends \PHPUnit\Framework\TestCase {
* @covers \MensBeam\HTML\DOM\Node::cloneInnerNode * @covers \MensBeam\HTML\DOM\Node::cloneInnerNode
* @covers \MensBeam\HTML\DOM\Node::cloneWrapperNode * @covers \MensBeam\HTML\DOM\Node::cloneWrapperNode
* @covers \MensBeam\HTML\DOM\Node::getInnerNode * @covers \MensBeam\HTML\DOM\Node::getInnerNode
* @covers \MensBeam\HTML\DOM\Node::hasChildNodes
* @covers \MensBeam\HTML\DOM\Node::isEqualInnerNode * @covers \MensBeam\HTML\DOM\Node::isEqualInnerNode
* @covers \MensBeam\HTML\DOM\Node::isEqualNode * @covers \MensBeam\HTML\DOM\Node::isEqualNode
* @covers \MensBeam\HTML\DOM\Node::preInsertionValidity * @covers \MensBeam\HTML\DOM\Node::preInsertionValidity
@ -301,7 +304,36 @@ class TestNode extends \PHPUnit\Framework\TestCase {
$this->assertSame('<body><template></template>ook<div></div></body>', (string)$d->body); $this->assertSame('<body><template></template>ook<div></div></body>', (string)$d->body);
} }
/** @covers \MensBeam\HTML\DOM\Node::isEqualNode */ /**
* @covers \MensBeam\HTML\DOM\Node::isEqualNode
*
* @covers \MensBeam\HTML\DOM\Comment::__construct
* @covers \MensBeam\HTML\DOM\Document::__construct
* @covers \MensBeam\HTML\DOM\Document::__get_implementation
* @covers \MensBeam\HTML\DOM\Document::createComment
* @covers \MensBeam\HTML\DOM\Document::createElement
* @covers \MensBeam\HTML\DOM\Document::createTextNode
* @covers \MensBeam\HTML\DOM\DocumentType::__construct
* @covers \MensBeam\HTML\DOM\DOMImplementation::__construct
* @covers \MensBeam\HTML\DOM\DOMImplementation::createDocumentType
* @covers \MensBeam\HTML\DOM\Element::__construct
* @covers \MensBeam\HTML\DOM\Element::setAttribute
* @covers \MensBeam\HTML\DOM\Node::__construct
* @covers \MensBeam\HTML\DOM\Node::appendChild
* @covers \MensBeam\HTML\DOM\Node::getInnerNode
* @covers \MensBeam\HTML\DOM\Node::isEqualInnerNode
* @covers \MensBeam\HTML\DOM\Node::preInsertionValidity
* @covers \MensBeam\HTML\DOM\Text::__construct
* @covers \MensBeam\HTML\DOM\InnerNode\Document::__construct
* @covers \MensBeam\HTML\DOM\InnerNode\Document::getWrapperNode
* @covers \MensBeam\HTML\DOM\InnerNode\NodeMap::get
* @covers \MensBeam\HTML\DOM\InnerNode\NodeMap::has
* @covers \MensBeam\HTML\DOM\InnerNode\NodeMap::key
* @covers \MensBeam\HTML\DOM\InnerNode\NodeMap::set
* @covers \MensBeam\HTML\DOM\InnerNode\Reflection::createFromProtectedConstructor
* @covers \MensBeam\HTML\DOM\InnerNode\Reflection::getProtectedProperty
* @covers \MensBeam\HTML\DOM\InnerNode\Reflection::setProtectedProperties
*/
public function testMethod_isEqualNode(): void { public function testMethod_isEqualNode(): void {
$d = new Document(); $d = new Document();
@ -333,7 +365,6 @@ class TestNode extends \PHPUnit\Framework\TestCase {
} }
/** /**
* @covers \MensBeam\HTML\DOM\Document::__construct * @covers \MensBeam\HTML\DOM\Document::__construct
* @covers \MensBeam\HTML\DOM\Document::__get_body * @covers \MensBeam\HTML\DOM\Document::__get_body
@ -371,12 +402,27 @@ class TestNode extends \PHPUnit\Framework\TestCase {
/** /**
* @covers \MensBeam\HTML\DOM\Node::isDefaultNamespace * @covers \MensBeam\HTML\DOM\Node::isDefaultNamespace
* *
* @covers \MensBeam\HTML\DOM\Attr::__get_namespaceURI
* @covers \MensBeam\HTML\DOM\Attr::__set_value
* @covers \MensBeam\HTML\DOM\Comment::__construct
* @covers \MensBeam\HTML\DOM\Document::__construct * @covers \MensBeam\HTML\DOM\Document::__construct
* @covers \MensBeam\HTML\DOM\Document::__get_body
* @covers \MensBeam\HTML\DOM\Document::__get_documentElement * @covers \MensBeam\HTML\DOM\Document::__get_documentElement
* @covers \MensBeam\HTML\DOM\Document::__get_implementation
* @covers \MensBeam\HTML\DOM\Document::createAttributeNS
* @covers \MensBeam\HTML\DOM\Document::createComment
* @covers \MensBeam\HTML\DOM\Document::createDocumentFragment
* @covers \MensBeam\HTML\DOM\Document::createElement * @covers \MensBeam\HTML\DOM\Document::createElement
* @covers \MensBeam\HTML\DOM\Document::createElementNS
* @covers \MensBeam\HTML\DOM\Document::validateAndExtract
* @covers \MensBeam\HTML\DOM\DocumentFragment::__construct
* @covers \MensBeam\HTML\DOM\DocumentType::__construct
* @covers \MensBeam\HTML\DOM\DOMImplementation::__construct * @covers \MensBeam\HTML\DOM\DOMImplementation::__construct
* @covers \MensBeam\HTML\DOM\DOMImplementation::createDocumentType
* @covers \MensBeam\HTML\DOM\Element::__construct * @covers \MensBeam\HTML\DOM\Element::__construct
* @covers \MensBeam\HTML\DOM\Element::setAttributeNode
* @covers \MensBeam\HTML\DOM\Element::setAttributeNodeNS
* @covers \MensBeam\HTML\DOM\Element::setAttributeNS
* @covers \MensBeam\HTML\DOM\Element::validateAndExtract
* @covers \MensBeam\HTML\DOM\Node::__construct * @covers \MensBeam\HTML\DOM\Node::__construct
* @covers \MensBeam\HTML\DOM\Node::__get_ownerDocument * @covers \MensBeam\HTML\DOM\Node::__get_ownerDocument
* @covers \MensBeam\HTML\DOM\Node::appendChild * @covers \MensBeam\HTML\DOM\Node::appendChild
@ -392,6 +438,7 @@ class TestNode extends \PHPUnit\Framework\TestCase {
* @covers \MensBeam\HTML\DOM\InnerNode\NodeMap::set * @covers \MensBeam\HTML\DOM\InnerNode\NodeMap::set
* @covers \MensBeam\HTML\DOM\InnerNode\Reflection::createFromProtectedConstructor * @covers \MensBeam\HTML\DOM\InnerNode\Reflection::createFromProtectedConstructor
* @covers \MensBeam\HTML\DOM\InnerNode\Reflection::getProtectedProperty * @covers \MensBeam\HTML\DOM\InnerNode\Reflection::getProtectedProperty
* @covers \MensBeam\HTML\DOM\InnerNode\Reflection::setProtectedProperties
*/ */
public function testMethod_isDefaultNamespace(): void { public function testMethod_isDefaultNamespace(): void {
$d = new Document(); $d = new Document();
@ -404,8 +451,8 @@ class TestNode extends \PHPUnit\Framework\TestCase {
$documentElement = $d->appendChild($d->createElement('html')); $documentElement = $d->appendChild($d->createElement('html'));
$documentElement->setAttributeNS(Parser::XMLNS_NAMESPACE, 'xmlns:poop💩', 'https://poop💩.poop'); $documentElement->setAttributeNS(Parser::XMLNS_NAMESPACE, 'xmlns:poop💩', 'https://poop💩.poop');
$body = $documentElement->appendChild($d->createElement('body')); $body = $documentElement->appendChild($d->createElement('body'));
$svg = $body->appendChild($d->createElementNS(Parser::SVG_NAMESPACE, 'svg')); $mathml = $body->appendChild($d->createElementNS(Parser::MATHML_NAMESPACE, 'mathml'));
$svg->setAttributeNS(Parser::XMLNS_NAMESPACE, 'xmlns:xlink', Parser::XLINK_NAMESPACE); $mathml->setAttributeNS(Parser::XMLNS_NAMESPACE, 'xmlns:xlink', Parser::XLINK_NAMESPACE);
$comment = $d->createComment('Ook'); $comment = $d->createComment('Ook');
// Detached comment // Detached comment
@ -433,8 +480,8 @@ class TestNode extends \PHPUnit\Framework\TestCase {
$this->assertTrue($d->isDefaultNamespace(Parser::HTML_NAMESPACE)); $this->assertTrue($d->isDefaultNamespace(Parser::HTML_NAMESPACE));
// HTML namespace on element // HTML namespace on element
$this->assertTrue($body->isDefaultNamespace(Parser::HTML_NAMESPACE)); $this->assertTrue($body->isDefaultNamespace(Parser::HTML_NAMESPACE));
// SVG namespace on svg element // MathML namespace on mathml element
$this->assertTrue($svg->isDefaultNamespace(Parser::SVG_NAMESPACE)); $this->assertTrue($mathml->isDefaultNamespace(Parser::MATHML_NAMESPACE));
// On detached XML element with null namespace // On detached XML element with null namespace
$this->assertTrue($detached->isDefaultNamespace(null)); $this->assertTrue($detached->isDefaultNamespace(null));
// Custom namespace on namespaced element // Custom namespace on namespaced element
@ -452,7 +499,50 @@ class TestNode extends \PHPUnit\Framework\TestCase {
} }
/** @covers \MensBeam\HTML\DOM\Node::lookupPrefix */ /**
* @covers \MensBeam\HTML\DOM\Node::lookupPrefix
*
* @covers \MensBeam\HTML\DOM\Attr::__get_namespaceURI
* @covers \MensBeam\HTML\DOM\Attr::__get_ownerElement
* @covers \MensBeam\HTML\DOM\Attr::__set_value
* @covers \MensBeam\HTML\DOM\Comment::__construct
* @covers \MensBeam\HTML\DOM\Document::__construct
* @covers \MensBeam\HTML\DOM\Document::__get_documentElement
* @covers \MensBeam\HTML\DOM\Document::__get_implementation
* @covers \MensBeam\HTML\DOM\Document::createAttributeNS
* @covers \MensBeam\HTML\DOM\Document::createComment
* @covers \MensBeam\HTML\DOM\Document::createDocumentFragment
* @covers \MensBeam\HTML\DOM\Document::createElement
* @covers \MensBeam\HTML\DOM\Document::createElementNS
* @covers \MensBeam\HTML\DOM\Document::validateAndExtract
* @covers \MensBeam\HTML\DOM\DocumentFragment::__construct
* @covers \MensBeam\HTML\DOM\DocumentType::__construct
* @covers \MensBeam\HTML\DOM\DOMImplementation::__construct
* @covers \MensBeam\HTML\DOM\DOMImplementation::createDocumentType
* @covers \MensBeam\HTML\DOM\Element::__construct
* @covers \MensBeam\HTML\DOM\Element::setAttributeNode
* @covers \MensBeam\HTML\DOM\Element::setAttributeNodeNS
* @covers \MensBeam\HTML\DOM\Element::setAttributeNS
* @covers \MensBeam\HTML\DOM\Element::validateAndExtract
* @covers \MensBeam\HTML\DOM\Node::__construct
* @covers \MensBeam\HTML\DOM\Node::__get_ownerDocument
* @covers \MensBeam\HTML\DOM\Node::__get_parentElement
* @covers \MensBeam\HTML\DOM\Node::__get_parentNode
* @covers \MensBeam\HTML\DOM\Node::appendChild
* @covers \MensBeam\HTML\DOM\Node::getInnerNode
* @covers \MensBeam\HTML\DOM\Node::locateNamespacePrefix
* @covers \MensBeam\HTML\DOM\Node::preInsertionValidity
* @covers \MensBeam\HTML\DOM\InnerNode\Document::__construct
* @covers \MensBeam\HTML\DOM\InnerNode\Document::__get_wrapperNode
* @covers \MensBeam\HTML\DOM\InnerNode\Document::getWrapperNode
* @covers \MensBeam\HTML\DOM\InnerNode\NodeMap::get
* @covers \MensBeam\HTML\DOM\InnerNode\NodeMap::has
* @covers \MensBeam\HTML\DOM\InnerNode\NodeMap::key
* @covers \MensBeam\HTML\DOM\InnerNode\NodeMap::set
* @covers \MensBeam\HTML\DOM\InnerNode\Reflection::createFromProtectedConstructor
* @covers \MensBeam\HTML\DOM\InnerNode\Reflection::getProtectedProperty
* @covers \MensBeam\HTML\DOM\InnerNode\Reflection::setProtectedProperties
*/
public function testMethod_lookupPrefix(): void { public function testMethod_lookupPrefix(): void {
$d = new Document(); $d = new Document();
$doctype = $d->appendChild($d->implementation->createDocumentType('html', '', '')); $doctype = $d->appendChild($d->implementation->createDocumentType('html', '', ''));
@ -493,7 +583,28 @@ class TestNode extends \PHPUnit\Framework\TestCase {
} }
/** @covers \MensBeam\HTML\DOM\Node::lookupNamespaceURI */ /**
* @covers \MensBeam\HTML\DOM\Node::lookupNamespaceURI
*
* @covers \MensBeam\HTML\DOM\Document::__construct
* @covers \MensBeam\HTML\DOM\Document::createElement
* @covers \MensBeam\HTML\DOM\DOMImplementation::__construct
* @covers \MensBeam\HTML\DOM\Element::__construct
* @covers \MensBeam\HTML\DOM\Node::__construct
* @covers \MensBeam\HTML\DOM\Node::appendChild
* @covers \MensBeam\HTML\DOM\Node::getInnerNode
* @covers \MensBeam\HTML\DOM\Node::locateNamespace
* @covers \MensBeam\HTML\DOM\Node::preInsertionValidity
* @covers \MensBeam\HTML\DOM\InnerNode\Document::__construct
* @covers \MensBeam\HTML\DOM\InnerNode\Document::__get_wrapperNode
* @covers \MensBeam\HTML\DOM\InnerNode\Document::getWrapperNode
* @covers \MensBeam\HTML\DOM\InnerNode\NodeMap::get
* @covers \MensBeam\HTML\DOM\InnerNode\NodeMap::has
* @covers \MensBeam\HTML\DOM\InnerNode\NodeMap::key
* @covers \MensBeam\HTML\DOM\InnerNode\NodeMap::set
* @covers \MensBeam\HTML\DOM\InnerNode\Reflection::createFromProtectedConstructor
* @covers \MensBeam\HTML\DOM\InnerNode\Reflection::getProtectedProperty
*/
public function testMethod_lookupNamespaceURI(): void { public function testMethod_lookupNamespaceURI(): void {
$d = new Document(); $d = new Document();
$d->appendChild($d->createElement('html')); $d->appendChild($d->createElement('html'));
@ -503,7 +614,33 @@ class TestNode extends \PHPUnit\Framework\TestCase {
} }
/** @covers \MensBeam\HTML\DOM\Node::normalize */ /**
* @covers \MensBeam\HTML\DOM\Node::normalize
*
* @covers \MensBeam\HTML\DOM\Collection::__construct
* @covers \MensBeam\HTML\DOM\Collection::__get_length
* @covers \MensBeam\HTML\DOM\Collection::count
* @covers \MensBeam\HTML\DOM\Document::__construct
* @covers \MensBeam\HTML\DOM\Document::__get_documentElement
* @covers \MensBeam\HTML\DOM\Document::createElement
* @covers \MensBeam\HTML\DOM\Document::createTextNode
* @covers \MensBeam\HTML\DOM\DOMImplementation::__construct
* @covers \MensBeam\HTML\DOM\Element::__construct
* @covers \MensBeam\HTML\DOM\Node::__construct
* @covers \MensBeam\HTML\DOM\Node::__get_childNodes
* @covers \MensBeam\HTML\DOM\Node::appendChild
* @covers \MensBeam\HTML\DOM\Node::getInnerNode
* @covers \MensBeam\HTML\DOM\Node::preInsertionValidity
* @covers \MensBeam\HTML\DOM\Text::__construct
* @covers \MensBeam\HTML\DOM\InnerNode\Document::__construct
* @covers \MensBeam\HTML\DOM\InnerNode\Document::getWrapperNode
* @covers \MensBeam\HTML\DOM\InnerNode\NodeMap::get
* @covers \MensBeam\HTML\DOM\InnerNode\NodeMap::has
* @covers \MensBeam\HTML\DOM\InnerNode\NodeMap::key
* @covers \MensBeam\HTML\DOM\InnerNode\NodeMap::set
* @covers \MensBeam\HTML\DOM\InnerNode\Reflection::createFromProtectedConstructor
* @covers \MensBeam\HTML\DOM\InnerNode\Reflection::getProtectedProperty
*/
public function testMethod_normalize(): void { public function testMethod_normalize(): void {
// Unless we implement Ranges PHP's DOM does this correctly. // Unless we implement Ranges PHP's DOM does this correctly.
$d = new Document(); $d = new Document();
@ -517,6 +654,77 @@ class TestNode extends \PHPUnit\Framework\TestCase {
} }
/** @covers \MensBeam\HTML\DOM\Node::replaceChild */
public function testMethod_replaceChild(): 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('<body>ook</body>', (string)$d->body);
$t = $d->body->replaceChild($d->createElement('template'), $ook);
$this->assertSame('<body><template></template></body>', (string)$d->body);
$d->body->replaceChild($d->createElement('br'), $t);
$this->assertSame('<body><br></body>', (string)$d->body);
}
public function provideMethod_replaceChild_errors(): iterable {
return [
[ function() {
$d = new Document();
$comment = $d->createComment('ook');
$comment->replaceChild($d->createTextNode('fail'), $d->createComment('ook'));
} ],
[ function() {
$d = new Document();
$documentElement = $d->appendChild($d->createElement('html'));
$body = $d->documentElement->appendChild($d->createElement('body'));
$body->replaceChild($documentElement, $d->createTextNode('ook'));
} ],
[ function() {
$d = new Document();
$documentElement = $d->appendChild($d->createElement('html'));
$body = $d->documentElement->appendChild($d->createElement('body'));
$documentElement->replaceChild($documentElement, $body);
} ],
[ function() {
$d = new Document();
$documentElement = $d->appendChild($d->createElement('html'));
$body = $d->documentElement->appendChild($d->createElement('body'));
$body->replaceChild($d->createTextNode('ook'), $documentElement);
}, DOMException::NOT_FOUND ],
[ function() {
$d = new Document();
$d2 = new Document();
$documentElement = $d->appendChild($d->createElement('html'));
$body = $d->documentElement->appendChild($d->createElement('body'));
$documentElement->replaceChild($d2, $body);
} ],
[ function() {
$d = new Document();
$documentElement = $d->appendChild($d->createElement('html'));
$d->replaceChild($d->createTextNode('ook'), $documentElement);
} ]
];
}
/**
* @dataProvider provideMethod_replaceChild_errors
* @covers \MensBeam\HTML\DOM\Node::replaceChild
*/
public function testMethod_replaceChild_errors(\Closure $closure, int $errorCode = DOMException::HIERARCHY_REQUEST_ERROR): void {
$this->expectException(DOMException::class);
$this->expectExceptionCode($errorCode);
$closure();
}
/** /**
* @covers \MensBeam\HTML\DOM\Node::__get_childNodes * @covers \MensBeam\HTML\DOM\Node::__get_childNodes
* *

Loading…
Cancel
Save