LoboEvolution/LoboEvolution

View on GitHub
LoboUnitTest/src/test/java/org/loboevolution/junit/DOMNodeTest.java

Summary

Maintainability
F
1 wk
Test Coverage
/*
 * MIT License
 *
 * Copyright (c) 2014 - 2024 LoboEvolution
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 * Contact info: ivan.difrancesco@yahoo.it
 */

package org.loboevolution.junit;

import org.htmlunit.cssparser.dom.DOMException;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.loboevolution.driver.LoboUnitTest;
import org.loboevolution.gui.LocalHtmlRendererConfig;
import org.loboevolution.html.dom.HTMLCollection;
import org.loboevolution.html.dom.nodeimpl.DOMImplementationImpl;
import org.loboevolution.html.node.*;
import org.loboevolution.http.UserAgentContext;

import static org.junit.jupiter.api.Assertions.*;

public class DOMNodeTest extends LoboUnitTest {

    private static Document document;
    private static DOMImplementationImpl impl;

    @BeforeAll
    public static void setUpBeforeClass() {
        final UserAgentContext context = new UserAgentContext(new LocalHtmlRendererConfig(), true);
        context.setUserAgentEnabled(false);
        impl = new DOMImplementationImpl(context);
    }

    @Test
    public void compareDocumentPosition1() {
        document = sampleHtmlFile();
        final Node html = document.getDocumentElement();
        final Element div1 = document.createElement("div");
        final Element div2 = document.createElement("div");
        html.appendChild(div1);
        html.appendChild(div2);
        assertEquals(Node.DOCUMENT_POSITION_FOLLOWING, div1.compareDocumentPosition(div2));
        assertEquals(Node.DOCUMENT_POSITION_PRECEDING, div2.compareDocumentPosition(div1));
        assertEquals(Node.DOCUMENT_POSITION_CONTAINED_BY + Node.DOCUMENT_POSITION_FOLLOWING, html.compareDocumentPosition(div1));
        assertEquals(Node.DOCUMENT_POSITION_CONTAINED_BY + Node.DOCUMENT_POSITION_FOLLOWING, html.compareDocumentPosition(div2));
        assertEquals(Node.DOCUMENT_POSITION_CONTAINS + Node.DOCUMENT_POSITION_PRECEDING, div1.compareDocumentPosition(html));
        assertEquals(Node.DOCUMENT_POSITION_CONTAINS + Node.DOCUMENT_POSITION_PRECEDING, div2.compareDocumentPosition(html));
        assertEquals(0, html.compareDocumentPosition(html));
        assertEquals(0, div1.compareDocumentPosition(div1));
        final Element p = document.createElement("p");
        div1.appendChild(p);
        assertEquals(Node.DOCUMENT_POSITION_CONTAINED_BY + Node.DOCUMENT_POSITION_FOLLOWING, div1.compareDocumentPosition(p));
        assertEquals(Node.DOCUMENT_POSITION_CONTAINS + Node.DOCUMENT_POSITION_PRECEDING, p.compareDocumentPosition(div1));
        assertEquals(Node.DOCUMENT_POSITION_CONTAINED_BY + Node.DOCUMENT_POSITION_FOLLOWING, html.compareDocumentPosition(p));
        assertEquals(Node.DOCUMENT_POSITION_CONTAINS + Node.DOCUMENT_POSITION_PRECEDING, p.compareDocumentPosition(html));
        assertEquals(Node.DOCUMENT_POSITION_PRECEDING, p.compareDocumentPosition(div2));
        assertEquals(Node.DOCUMENT_POSITION_FOLLOWING, div2.compareDocumentPosition(p));
        final Document otherdoc = impl.createDocument(null, "html", null);
        final Element otherDocElm = otherdoc.getDocumentElement();
        assertEquals(Node.DOCUMENT_POSITION_DISCONNECTED, div2.compareDocumentPosition(otherDocElm));
        assertEquals(Node.DOCUMENT_POSITION_DISCONNECTED, otherDocElm.compareDocumentPosition(div2));
    }

    @Test
    public void normalize() {
        document = sampleHtmlFile();
        assertEquals(2, document.getChildNodes().getLength());
        final Element elm = document.createElement("body");
        final Element html = document.getDocumentElement();
        html.appendChild(document.createTextNode("\n     "));
        html.appendChild(document.createTextNode("\t     "));
        html.appendChild(document.createTextNode("\n     "));
        html.appendChild(elm);
        final Text foo = document.createTextNode("foo");
        final Text bar = document.createTextNode("bar");
        elm.appendChild(document.createTextNode(" \t  "));
        elm.appendChild(foo);
        elm.appendChild(document.createTextNode("     "));
        elm.appendChild(bar);
        elm.appendChild(document.createTextNode("\n   "));
        elm.appendChild(document.createTextNode("   "));
        assertEquals(6, elm.getChildNodes().getLength());
        elm.normalize();
        assertEquals(1, elm.getChildNodes().getLength());

        html.appendChild(document.createTextNode("\n     "));
        html.appendChild(document.createTextNode("\t     "));
        html.appendChild(document.createTextNode("\n     "));

        assertEquals(1, html.getChildNodes().getLength());
        assertEquals(1, elm.getChildNodes().getLength());
    }

    @Test
    public void normalize2() {
        document = sampleHtmlFile();
        assertEquals(2, document.getChildNodes().getLength());
        final Element elm = document.createElement("body");
        final Element html = document.getDocumentElement();
        html.appendChild(document.createComment(" Comment "));
        html.appendChild(document.createTextNode("\n     "));
        html.appendChild(document.createTextNode("\t     "));
        html.appendChild(document.createTextNode("\n     "));
        html.appendChild(elm);
        final Comment comment = document.createComment("Hi");
        final Text foo = document.createTextNode("foo");
        final Text bar = document.createTextNode("bar \u212b");
        elm.appendChild(comment);
        elm.appendChild(document.createTextNode(" \t  "));
        elm.appendChild(foo);
        elm.appendChild(document.createTextNode("     "));
        elm.appendChild(document.createTextNode("     "));
        elm.appendChild(bar);
        elm.appendChild(document.createTextNode("\n   "));
        final Comment comment2 = document.createComment("Hi");
        elm.appendChild(comment2);
        assertEquals(8, elm.getChildNodes().getLength());
        elm.normalize();
        assertEquals(4, elm.getChildNodes().getLength());
        //
        final DOMConfiguration config = document.getDomConfig();
        assertTrue(config.canSetParameter("normalize-characters", false));
        assertTrue(config.canSetParameter("normalize-characters", true));
        assertFalse((Boolean) config.getParameter("normalize-characters"));
        config.setParameter("normalize-characters", true);
        assertTrue((Boolean) config.getParameter("normalize-characters"));
        elm.normalize();
        assertEquals(4, elm.getChildNodes().getLength());
        assertEquals(" foo bar \u00c5 ", elm.getChildNodes().item(1).getNodeValue());
        //
        html.appendChild(document.createTextNode("\n     "));
        html.appendChild(document.createTextNode("\t     "));
        html.appendChild(document.createTextNode("\n     "));
        html.appendChild(document.createComment(" Middle comment "));
        html.appendChild(document.createTextNode(""));
        html.appendChild(document.createComment(" End comment "));
        assertEquals(11, html.getChildNodes().getLength());
        document.normalizeDocument();
        assertEquals(6, html.getChildNodes().getLength());
        assertEquals(4, elm.getChildNodes().getLength());
        assertEquals(" ", html.getChildNodes().item(3).getNodeValue());
        assertEquals(Node.COMMENT_NODE, html.getChildNodes().item(4).getNodeType());
        assertEquals(Node.COMMENT_NODE, html.getChildNodes().item(5).getNodeType());
        // Use computed styles (same result, just slower)
        assertTrue(config.canSetParameter("use-computed-styles", false));
        assertTrue(config.canSetParameter("use-computed-styles", true));
        assertFalse((boolean) config.getParameter("use-computed-styles"));
        config.setParameter("use-computed-styles", true);
        assertTrue((boolean) config.getParameter("use-computed-styles"));
        document.normalizeDocument();
        assertEquals(6, html.getChildNodes().getLength());
        assertEquals(4, elm.getChildNodes().getLength());
        // Remove comment nodes
        assertTrue(config.canSetParameter("comments", false));
        assertTrue(config.canSetParameter("comments", true));
        assertTrue((boolean) config.getParameter("comments"));
        config.setParameter("comments", false);
        document.normalizeDocument();
        assertEquals(4, html.getChildNodes().getLength());
        assertEquals(1, elm.getChildNodes().getLength());
        // Other canSetParameter cases.
        assertTrue(config.canSetParameter("css-whitespace-processing", false));
        assertTrue(config.canSetParameter("css-whitespace-processing", true));
        assertTrue((boolean) config.getParameter("css-whitespace-processing"));
        //
        assertTrue(config.canSetParameter("canonical-form", false));
        assertTrue(config.canSetParameter("check-character-normalization", false));
        assertTrue(config.canSetParameter("datatype-normalization", false));
        assertTrue(config.canSetParameter("validate", false));
        assertTrue(config.canSetParameter("validate-if-schema", false));
        assertTrue(config.canSetParameter("element-content-whitespace", true));
        assertTrue(config.canSetParameter("cdata-sections", true));
        assertTrue(config.canSetParameter("namespaces", true));
        assertFalse(config.canSetParameter("namespaces", false));
        assertTrue(config.canSetParameter("namespace-declarations", true));
        assertFalse(config.canSetParameter("namespace-declarations", false));
        assertTrue(config.canSetParameter("well-formed", true));
        assertTrue(config.canSetParameter("well-formed", false));
        assertFalse(config.canSetParameter("split-cdata-sections", true));
        assertFalse(config.canSetParameter("split-cdata-sections", false));
        //
        final DOMStringList names = config.getParameterNames();
        assertEquals(4, names.getLength());
        assertTrue(names.contains("css-whitespace-processing"));
        assertTrue(names.contains("normalize-characters"));
    }

    @Test
    public void isSameNode() {
        document = sampleHtmlFile();
        final Element elm1 = document.createElement("p");
        elm1.setAttribute("foo", "bar");
        final Text foo1 = document.createTextNode("foo");
        elm1.appendChild(foo1);
        assertTrue(elm1.isSameNode(elm1));
        assertFalse(elm1.isSameNode(foo1));
    }

    @Test
    public void isEqualNode() {
        document = sampleHtmlFile();
        final Element elm1 = document.createElement("p");
        final Element elm2 = document.createElement("p");
        assertTrue(elm1.isEqualNode(elm2));
        elm1.setAttribute("foo", "bar");
        assertFalse(elm1.isEqualNode(elm2));
        elm2.setAttribute("foo", "foo");
        assertFalse(elm1.isEqualNode(elm2));
        elm2.setAttribute("foo", "bar");
        assertTrue(elm1.isEqualNode(elm2));
        elm2.removeAttribute("foo");
        final Text foo1 = document.createTextNode("foo");
        elm1.appendChild(foo1);
        assertFalse(elm1.isEqualNode(elm2));
        elm2.setAttribute("foo", "bar");
        assertFalse(elm1.isEqualNode(elm2));
        final Text foo2 = document.createTextNode("foo");
        elm2.appendChild(foo2);
        assertTrue(elm1.isEqualNode(elm2));
        final Text bar = document.createTextNode("bar");
        elm2.replaceChild(bar, foo2);
        assertFalse(elm1.isEqualNode(elm2));
    }

    @Test
    public void getNodeValue() {
        document = sampleHtmlFile();
        final Element elm = document.createElement("p");
        assertEquals("P", elm.getNodeName());
        assertNull(elm.getNodeValue());
        final Text text = document.createTextNode("foo");
        assertEquals("#text", text.getNodeName());
        assertEquals("foo", text.getNodeValue());
        text.setNodeValue("bar");
        assertEquals("bar", text.getNodeValue());
        final Attr attr = document.createAttribute("id");
        attr.setValue("fooid");
        assertEquals("id", attr.getNodeName());
        assertEquals("fooid", attr.getNodeValue());
        attr.setNodeValue("barid");
        assertEquals("barid", attr.getNodeValue());
        final CDATASection cdata = document.createCDATASection("var j = 1");
        assertEquals("#cdata-section", cdata.getNodeName());
        assertEquals("var j = 1", cdata.getNodeValue());
        cdata.setNodeValue("foo");
        assertEquals("foo", cdata.getNodeValue());
        final Comment comment = document.createComment("***");
        assertEquals("#comment", comment.getNodeName());
        assertEquals("***", comment.getNodeValue());
        comment.setNodeValue("comment");
        assertEquals("comment", comment.getNodeValue());
        final DocumentFragment fragment = document.createDocumentFragment();
        assertEquals("[object DocumentFragment]", fragment.getNodeName());
        assertNull(fragment.getNodeValue());
        assertEquals("[object HTMLDocument]", document.getNodeName());
        assertNull(document.getNodeValue());
        final ProcessingInstruction pi = document.createProcessingInstruction("xml-stylesheet",
                "type=\"text/css\" href=\"sheet.css\"");
        assertEquals("xml-stylesheet", pi.getNodeName());
        assertEquals("type=\"text/css\" href=\"sheet.css\"", pi.getNodeValue());
        final DocumentType dt = impl.createDocumentType("xhtml", "-//W3C//DTD XHTML 1.1//EN", "w3c/xhtml11.dtd");
        assertEquals("xhtml", dt.getNodeName());
        assertNull(dt.getNodeValue());
    }

    @Test
    public void getPreviousSibling() throws DOMException {
        document = sampleHtmlFile();
        final Element html = document.getDocumentElement();
        final Element elm1 = document.createElement("div");
        html.appendChild(elm1);
        assertSame(html, elm1.getParentNode());
        final Element elm2 = document.createElement("p");
        html.appendChild(elm2);
        assertSame(html, elm2.getParentNode());
        assertSame(elm1, elm2.getPreviousSibling());
        assertSame(elm2, elm1.getNextSibling());
        assertNotNull(elm1.getPreviousSibling());
        assertNull(elm2.getNextSibling());
    }

    @Test
    public void getFirstChild() throws DOMException {
        document = sampleHtmlFile();
        final Element html = document.getDocumentElement();
        final Element elm1 = document.createElement("div");
        html.appendChild(elm1);
        final Element elm2 = document.createElement("p");
        html.appendChild(elm2);
        assertSame(document.getHead(), html.getFirstChild());
        assertSame(elm2, html.getLastChild());
        assertNull(elm1.getFirstChild());
        assertNull(elm1.getLastChild());
    }

    @Test
    public void testDocumentFragment() throws DOMException {
        document = sampleHtmlFile();
        final DocumentFragment fragment = document.createDocumentFragment();
        final Element div = document.createElement("div");
        div.appendChild(document.createElement("span"));
        div.appendChild(document.createTextNode("text under div"));
        div.appendChild(document.createElement("i"));
        final Element p = document.createElement("p");
        p.appendChild(document.createElement("img"));
        p.appendChild(document.createTextNode("text under p"));
        p.appendChild(document.createElement("b"));
        fragment.appendChild(div);
        fragment.appendChild(p);
        assertSame(fragment.getFirstChild(), div);
        assertSame(fragment.getLastChild(), p);
        assertSame(div.getNextSibling(), p);
        assertSame(p.getPreviousSibling(), div);
        assertSame(div.getNextElementSibling(), p);
        assertSame(p.getPreviousElementSibling(), div);
    }

    private DocumentFragment createDocumentFragment() {
        final DocumentFragment fragment = document.createDocumentFragment();
        final Element div = document.createElement("div");
        div.appendChild(document.createElement("span"));
        div.appendChild(document.createTextNode("text under div"));
        div.appendChild(document.createElement("i"));
        final Element p = document.createElement("p");
        p.appendChild(document.createElement("img"));
        p.appendChild(document.createTextNode("text under p"));
        p.appendChild(document.createElement("b"));
        fragment.appendChild(div);
        fragment.appendChild(p);
        return fragment;
    }

    @Test
    public void prependChild() throws DOMException {
        document = sampleHtmlFile();
        final Element html = document.getDocumentElement();
        final Element elm = document.createElement("body");
        final ProcessingInstruction pi = document.createProcessingInstruction("xml-foo", "bar");
        final DocumentType docType = impl.createDocumentType("html", null, null);
        assertTrue(html.hasChildNodes());
        Node appended = html.prependChild(elm);
        assertTrue(html.hasChildNodes());
        assertSame(appended, elm);
        assertSame(html, elm.getParentNode());
        assertSame(appended, html.getChildNodes().item(0));
        assertSame(appended, html.getChildren().item(0));
        assertNotNull(html.getChildNodes().item(1));
        assertNotNull(html.getChildren().item(1));
        assertNull(html.getChildNodes().item(-1));
        assertNull(html.getChildren().item(-1));
        assertSame(document, elm.getOwnerDocument());
        assertSame(document, html.getOwnerDocument());
        final Attr attr = document.createAttribute("id");
        //
        try {
            elm.prependChild(attr);
            fail("Must throw exception.");
        } catch (final DOMException e) {
            assertEquals(DOMException.HIERARCHY_REQUEST_ERR, e.getCode());
        }
        try {
            elm.prependChild(document);
            fail("Must throw exception.");
        } catch (final DOMException e) {
            assertEquals(DOMException.HIERARCHY_REQUEST_ERR, e.getCode());
        }
        try {
            elm.prependChild(docType);
            fail("Must throw exception.");
        } catch (final DOMException e) {
            assertNull(docType.getParentNode());
            assertNull(docType.getOwnerDocument());
            assertEquals(DOMException.HIERARCHY_REQUEST_ERR, e.getCode());
        }
        try {
            elm.prependChild(elm);
            fail("Must throw exception.");
        } catch (final DOMException e) {
            assertEquals(DOMException.HIERARCHY_REQUEST_ERR, e.getCode());
        }
        try {
            elm.prependChild(html);
            fail("Must throw exception.");
        } catch (final DOMException e) {
            assertEquals(DOMException.HIERARCHY_REQUEST_ERR, e.getCode());
        }

        final DocumentFragment fragment = createDocumentFragment();
        try {
            fragment.prependChild(docType);
            fail("Must throw exception.");
        } catch (final DOMException e) {
            assertNull(docType.getParentNode());
            assertEquals(DOMException.HIERARCHY_REQUEST_ERR, e.getCode());
        }
        elm.prependChild(pi);
        assertTrue(elm.hasChildNodes());
        assertSame(pi, elm.getChildNodes().item(0));
        final Text text = document.createTextNode("foo");
        appended = elm.prependChild(text);
        assertSame(appended, text);
        assertSame(pi, text.getNextSibling());
        assertSame(text, pi.getPreviousSibling());
        assertSame(appended, elm.getChildNodes().item(0));
        assertNotNull(text.getNextElementSibling());
        assertNull(text.getPreviousElementSibling());
        // Test appending to void elements
        final Element head = document.createElement("head");
        html.prependChild(head);
        assertSame(head, html.getChildNodes().item(0));
        assertSame(head, html.getChildren().item(0));
        final Element base = document.createElement("base");
        head.prependChild(base);
        assertSame(base, head.getChildNodes().item(0));
        assertSame(base, head.getChildren().item(0));
        final Element base2 = document.createElement("base");
        try {
            head.prependChild(base2);
            fail("Must throw exception.");
        } catch (final DOMException e) {
            assertEquals(DOMException.HIERARCHY_REQUEST_ERR, e.getCode());
        }
        assertFalse(base.hasChildNodes());
        try {
            base.prependChild(document.createTextNode("foo"));
            fail("Must throw exception.");
        } catch (final DOMException e) {
            assertEquals(DOMException.HIERARCHY_REQUEST_ERR, e.getCode());
        }
        assertFalse(base.hasChildNodes());
        final Element link = document.createElement("link");
        try {
            link.prependChild(document.createTextNode("foo"));
            fail("Must throw exception.");
        } catch (final DOMException e) {
            assertEquals(DOMException.HIERARCHY_REQUEST_ERR, e.getCode());
        }
        assertFalse(link.hasChildNodes());
        final Element meta = document.createElement("meta");
        try {
            meta.prependChild(document.createTextNode("foo"));
            fail("Must throw exception.");
        } catch (final DOMException e) {
            assertEquals(DOMException.HIERARCHY_REQUEST_ERR, e.getCode());
        }
        assertFalse(meta.hasChildNodes());
        assertNull(meta.getChildNodes().item(0));
        assertNull(meta.getChildren().item(0));
        // Document fragment
        final Node first = fragment.getFirstChild();
        assertEquals(2, elm.getChildNodes().getLength());
        elm.prependChild(fragment);
        assertNotSame(fragment, elm.getFirstChild());
        assertEquals(4, elm.getChildNodes().getLength());
        assertSame(first, elm.getFirstChild());
        assertNotNull(fragment.getFirstChild());
        assertNotNull(fragment.getLastChild());
        assertNull(fragment.getParentNode());
    }

    @Test
    public void testAppendChild() throws DOMException {
        document = sampleHtmlFile();
        final Element html = document.getDocumentElement();
        final Element elm = document.createElement("body");
        final ProcessingInstruction pi = document.createProcessingInstruction("xml-foo", "bar");
        final DocumentType docType = impl.createDocumentType("html", null, null);
        assertTrue(html.hasChildNodes());
        Node appended = html.appendChild(elm);
        assertTrue(html.hasChildNodes());
        assertSame(appended, elm);
        assertSame(html, elm.getParentNode());
        assertSame(appended, html.getChildNodes().item(2));
        assertSame(appended, html.getChildren().item(2));
        assertNull(html.getChildNodes().item(-1));
        assertNull(html.getChildren().item(-1));
        assertSame(document, elm.getOwnerDocument());
        assertSame(document, html.getOwnerDocument());
        final Attr attr = document.createAttribute("id");
        final DocumentFragment fragment = createDocumentFragment();
        //
        try {
            docType.appendChild(fragment);
            fail("Must throw exception.");
        } catch (final DOMException e) {
            assertNull(fragment.getParentNode());
            assertEquals(DOMException.HIERARCHY_REQUEST_ERR, e.getCode());
        }
        //
        try {
            elm.appendChild(attr);
            fail("Must throw exception.");
        } catch (final DOMException e) {
            assertEquals(DOMException.HIERARCHY_REQUEST_ERR, e.getCode());
        }
        try {
            elm.appendChild(document);
            fail("Must throw exception.");
        } catch (final DOMException e) {
            assertEquals(DOMException.HIERARCHY_REQUEST_ERR, e.getCode());
        }
        try {
            elm.appendChild(docType);
            fail("Must throw exception.");
        } catch (final DOMException e) {
            assertNull(docType.getParentNode());
            assertNull(docType.getOwnerDocument());
            assertEquals(DOMException.HIERARCHY_REQUEST_ERR, e.getCode());
        }
        try {
            elm.appendChild(elm);
            fail("Must throw exception.");
        } catch (final DOMException e) {
            assertEquals(DOMException.HIERARCHY_REQUEST_ERR, e.getCode());
        }
        try {
            elm.appendChild(html);
            fail("Must throw exception.");
        } catch (final DOMException e) {
            assertEquals(DOMException.HIERARCHY_REQUEST_ERR, e.getCode());
        }

        final Text text = document.createTextNode("text inside elm");
        try {
            text.appendChild(document);
            fail("Must throw exception.");
        } catch (final DOMException e) {
            assertEquals(DOMException.HIERARCHY_REQUEST_ERR, e.getCode());
        }
        try {
            text.appendChild(text);
            fail("Must throw exception.");
        } catch (final DOMException e) {
            assertNull(text.getParentNode());
            assertEquals(DOMException.HIERARCHY_REQUEST_ERR, e.getCode());
        }

        try {
            text.appendChild(elm);
            fail("Must throw exception.");
        } catch (final DOMException e) {
            assertNotNull(elm.getParentNode());
            assertEquals(DOMException.HIERARCHY_REQUEST_ERR, e.getCode());
        }
        try {
            text.appendChild(attr);
            fail("Must throw exception.");
        } catch (final DOMException e) {
            assertEquals(DOMException.HIERARCHY_REQUEST_ERR, e.getCode());
        }
        try {
            text.appendChild(pi);
            fail("Must throw exception.");
        } catch (final DOMException e) {
            assertNull(pi.getParentNode());
            assertEquals(DOMException.HIERARCHY_REQUEST_ERR, e.getCode());
        }
        try {
            text.appendChild(docType);
            fail("Must throw exception.");
        } catch (final DOMException e) {
            assertNull(docType.getParentNode());
            assertEquals(DOMException.HIERARCHY_REQUEST_ERR, e.getCode());
        }
        try {
            text.appendChild(fragment);
            fail("Must throw exception.");
        } catch (final DOMException e) {
            assertNull(fragment.getParentNode());
            assertEquals(DOMException.HIERARCHY_REQUEST_ERR, e.getCode());
        }
        //
        try {
            attr.appendChild(text);
            fail("Must throw exception.");
        } catch (final DOMException e) {
            assertNull(text.getParentNode());
            assertEquals(DOMException.NOT_SUPPORTED_ERR, e.getCode());
        }
        try {
            attr.appendChild(pi);
            fail("Must throw exception.");
        } catch (final DOMException e) {
            assertNull(pi.getParentNode());
            assertEquals(DOMException.NOT_SUPPORTED_ERR, e.getCode());
        }
        try {
            attr.appendChild(docType);
            fail("Must throw exception.");
        } catch (final DOMException e) {
            assertNull(docType.getParentNode());
            assertEquals(DOMException.NOT_SUPPORTED_ERR, e.getCode());
        }
        try {
            attr.appendChild(fragment);
            fail("Must throw exception.");
        } catch (final DOMException e) {
            assertNull(fragment.getParentNode());
            assertEquals(DOMException.NOT_SUPPORTED_ERR, e.getCode());
        }
        //
        try {
            pi.appendChild(fragment);
            fail("Must throw exception.");
        } catch (final DOMException e) {
            assertNull(fragment.getParentNode());
            assertEquals(DOMException.HIERARCHY_REQUEST_ERR, e.getCode());
        }
        //
        try {
            pi.appendChild(docType);
            fail("Must throw exception.");
        } catch (final DOMException e) {
            assertNull(docType.getParentNode());
            assertEquals(DOMException.HIERARCHY_REQUEST_ERR, e.getCode());
        }
        try {
            fragment.appendChild(docType);
            fail("Must throw exception.");
        } catch (final DOMException e) {
            assertNull(docType.getParentNode());
            assertEquals(DOMException.HIERARCHY_REQUEST_ERR, e.getCode());
        }
        elm.appendChild(pi);
        assertTrue(elm.hasChildNodes());
        assertSame(pi, elm.getChildNodes().item(0));
        appended = elm.appendChild(text);
        assertSame(appended, text);
        assertSame(pi, text.getPreviousSibling());
        assertSame(text, pi.getNextSibling());
        assertSame(appended, elm.getChildNodes().item(1));
        assertNull(text.getNextElementSibling());
        assertNotNull(text.getPreviousElementSibling());
        // Test appending to void elements
        final Element head = document.createElement("head");
        html.appendChild(head);
        final Element base = document.createElement("base");
        head.appendChild(base);
        assertSame(base, head.getChildNodes().item(0));
        assertSame(base, head.getChildren().item(0));
        assertFalse(base.hasChildNodes());
        assertFalse(base.hasChildNodes());
        final Element link = document.createElement("link");
        assertFalse(link.hasChildNodes());
        final Element meta = document.createElement("meta");
        assertFalse(meta.hasChildNodes());
        assertNull(meta.getChildNodes().item(0));
        assertNull(meta.getChildren().item(0));
        // Document fragment
        final Node last = fragment.getLastChild();
        assertEquals(2, elm.getChildNodes().getLength());
        elm.appendChild(fragment);
        assertEquals(3, elm.getChildNodes().getLength());
        assertSame(fragment, elm.getLastChild());
        assertNotNull(fragment.getFirstChild());
        assertNotNull(fragment.getLastChild());
        assertNotNull(fragment.getParentNode());
    }

    @Test
    public void insertBefore() throws DOMException {
        document = sampleHtmlFile();
        final Element html = document.getDocumentElement();
        final Element elm1 = document.createElement("p");
        html.appendChild(elm1);
        assertSame(html, elm1.getParentNode());
        assertEquals(3, html.getChildNodes().getLength());
        final Element elm2 = document.createElement("div");
        Element elm = (Element) html.insertBefore(elm2, elm1);
        assertSame(elm2, elm);
        assertSame(elm2, elm1.getPreviousSibling());
        assertSame(elm2, elm1.getPreviousElementSibling());
        assertSame(elm1, elm2.getNextSibling());
        assertSame(elm1, elm2.getNextElementSibling());
        assertEquals(4, html.getChildNodes().getLength());
        assertSame(elm2, html.getChildNodes().item(2));
        assertSame(html, elm2.getParentNode());
        final Element elm3 = document.createElement("div");
        elm = (Element) html.insertBefore(elm3, null);
        assertSame(elm, elm3);
        assertEquals(5, html.getChildNodes().getLength());
        assertSame(elm3, html.getChildNodes().item(4));
    }

    @Test
    public void insertBefore2() throws DOMException {
        document = sampleHtmlFile();
        final Element html = document.getDocumentElement();
        final Element body = document.createElement("body");
        html.appendChild(body);
        final Element span = document.createElement("span");
        body.appendChild(span);
        assertSame(body, span.getParentNode());
        assertFalse(span.hasChildNodes());
        final Text text = document.createTextNode("foo");
        span.appendChild(text);
        assertTrue(span.hasChildNodes());
        final Text text2 = document.createTextNode("bar");
        body.appendChild(text2);
        assertSame(body, text2.getParentNode());
        final Element div = document.createElement("div");
        div.appendChild(document.createTextNode("inside div"));
        body.appendChild(div);
        assertSame(body, div.getParentNode());
        final Element p = document.createElement("p");
        p.appendChild(document.createTextNode("inside p"));
        body.appendChild(p);
        assertSame(body, p.getParentNode());
        assertSame(span.getNextSibling(), text2);
        assertSame(text2.getNextSibling(), div);
        assertSame(div.getNextSibling(), p);
        assertNull(p.getNextSibling());
        assertSame(span.getNextElementSibling(), div);
        assertSame(text2.getNextElementSibling(), div);
        assertSame(div.getNextElementSibling(), p);
        assertNull(p.getNextElementSibling());
        assertSame(span, body.getFirstChild());
        assertSame(span, body.getFirstElementChild());
        assertSame(p, body.getLastChild());
        assertSame(p, body.getLastElementChild());

        HTMLCollection listspan = body.getElementsByTagName("span");
        HTMLCollection listdiv = body.getElementsByTagName("div");
        HTMLCollection listp = body.getElementsByTagName("p");
        assertEquals(1, listspan.getLength());
        assertEquals(1, listdiv.getLength());
        assertEquals(1, listp.getLength());

        assertSame(p.getPreviousSibling(), div);
        assertSame(p.getPreviousElementSibling(), div);
        assertSame(div.getPreviousSibling(), text2);
        assertSame(div.getPreviousElementSibling(), span);
        assertSame(text2.getPreviousSibling(), span);
        assertSame(text2.getPreviousElementSibling(), span);
        assertNull(span.getPreviousSibling());
        assertNull(span.getPreviousElementSibling());

        final Element p2 = document.createElement("p");
        Element elm = (Element) body.insertBefore(p2, div);
        assertSame(p2, elm);
        assertSame(p2, div.getPreviousSibling());
        assertSame(p2, div.getPreviousElementSibling());
        assertSame(div, p2.getNextSibling());
        assertSame(div, p2.getNextElementSibling());
        assertEquals(5, body.getChildNodes().getLength());
        assertSame(p2, body.getChildNodes().item(2));
        assertSame(body, p2.getParentNode());

        listspan = body.getElementsByTagName("span");
        listdiv = body.getElementsByTagName("div");
        listp = body.getElementsByTagName("p");

        assertEquals(1, listspan.getLength());
        assertEquals(1, listdiv.getLength());
        assertEquals(2, listp.getLength());

        final Element elm3 = document.createElement("div");
        elm = (Element) body.insertBefore(elm3, null);
        assertSame(elm, elm3);
        assertEquals(6, body.getChildNodes().getLength());
        assertEquals(5, body.getChildren().getLength());
        assertSame(span, body.getChildNodes().item(0));
        assertSame(text2, body.getChildNodes().item(1));
        assertSame(p2, body.getChildNodes().item(2));
        assertSame(div, body.getChildNodes().item(3));
        assertSame(p, body.getChildNodes().item(4));
        assertSame(elm, body.getChildNodes().item(5));
        assertSame(span, body.getChildren().item(0));
        assertSame(p2, body.getChildren().item(1));
        assertSame(div, body.getChildren().item(2));
        assertSame(p, body.getChildren().item(3));
        assertSame(elm, body.getChildren().item(4));
        assertSame(body, elm.getParentNode());
        assertSame(p, elm.getPreviousSibling());
        assertSame(p, elm.getPreviousElementSibling());
        assertSame(elm, p.getNextSibling());
        assertSame(elm, p.getNextElementSibling());
        assertNull(elm.getNextSibling());
        assertNull(elm.getNextElementSibling());

        listspan = body.getElementsByTagName("span");
        listdiv = body.getElementsByTagName("div");
        listp = body.getElementsByTagName("p");

        assertEquals(1, listspan.getLength());
        assertEquals(2, listdiv.getLength());
        assertEquals(2, listp.getLength());
    }

    @Test
    public void insertBeforeMyself() throws DOMException {
        document = sampleHtmlFile();
        final Element html = document.getDocumentElement();
        final Element elm1 = document.createElement("div");
        html.appendChild(elm1);
        final Element elm2 = document.createElement("p");
        html.appendChild(elm2);
        assertSame(elm1, elm2.getPreviousSibling());
        assertSame(elm1, elm2.getPreviousElementSibling());
        assertSame(elm2, elm1.getNextSibling());
        assertSame(elm2, elm1.getNextElementSibling());
        assertSame(html, elm1.getParentNode());
        assertEquals(4, html.getChildNodes().getLength());
        assertSame(elm1, html.insertBefore(elm1, elm1));
        assertSame(elm1, elm2.getPreviousSibling());
        assertSame(elm1, elm2.getPreviousElementSibling());
        assertSame(elm2, elm1.getNextSibling());
        assertSame(elm2, elm1.getNextElementSibling());
        assertEquals(4, html.getChildNodes().getLength());
        assertSame(elm2, html.insertBefore(elm2, elm2));
        assertSame(elm1, elm2.getPreviousSibling());
        assertSame(elm1, elm2.getPreviousElementSibling());
        assertSame(elm2, elm1.getNextSibling());
        assertSame(elm2, elm1.getNextElementSibling());
    }

    @Test
    public void insertBeforeDF() throws DOMException {
        document = sampleHtmlFile();
        final Element html = document.getDocumentElement();
        final Element body = document.createElement("body");
        html.appendChild(body);
        final Element elm1 = document.createElement("p");
        body.appendChild(elm1);
        final Element elm2 = document.createElement("div");
        body.insertBefore(elm2, elm1);
        final Element elm3 = document.createElement("span");
        body.insertBefore(elm3, elm1);
        assertEquals(3, body.getChildNodes().getLength());
        final DocumentFragment fragment = createDocumentFragment();
        body.insertBefore(fragment, elm3);
        assertEquals(4, body.getChildNodes().getLength());
        assertEquals("SPAN", body.getChildNodes().item(2).getNodeName());
        assertEquals("P", body.getChildNodes().item(3).getNodeName());
        assertNotNull(fragment.getFirstChild());
        assertNotNull(fragment.getLastChild());
        assertNotNull(fragment.getParentNode());
    }

    @Test
    public void removeChild() throws DOMException {
        document = sampleHtmlFile();
        final Element html = document.getDocumentElement();
        Element elm = document.createElement("body");
        html.appendChild(elm);
        assertSame(html, elm.getParentNode());
        assertSame(document.getHead(), html.getFirstChild());
        assertSame(elm, html.getLastChild());
        assertSame(document.getHead(), html.getFirstElementChild());
        assertSame(elm, html.getLastElementChild());
        final Attr attr = document.createAttribute("id");
        attr.setValue("bodyId");
        assertFalse(elm.hasAttributes());
        elm.setAttributeNode(attr);
        assertTrue(elm.hasAttributes());
        assertFalse(elm.hasChildNodes());
        assertNotNull(attr.getParentNode());
        Text text = document.createTextNode("foo");
        elm.appendChild(text);
        assertTrue(elm.hasChildNodes());
        assertSame(elm, text.getParentNode());
        text = (Text) elm.removeChild(text);
        assertFalse(elm.hasChildNodes());
        assertNull(text.getParentNode());
        assertNull(text.getNextSibling());
        assertNull(text.getPreviousSibling());
        assertNull(text.getNextElementSibling());
        assertNull(text.getPreviousSibling());
        assertNull(text.getPreviousElementSibling());
        elm.removeAttribute(attr.getName());
        assertFalse(elm.hasAttributes());
        elm = (Element) html.removeChild(elm);
        assertTrue(html.hasChildNodes());
        assertNotNull(html.getFirstChild());
        assertNotNull(html.getLastChild());
        assertNull(elm.getParentNode());
        assertNull(elm.getNextSibling());
        assertNull(elm.getPreviousSibling());
        assertNull(elm.getNextElementSibling());
        assertNull(elm.getPreviousSibling());
        assertNull(elm.getPreviousElementSibling());
    }

    @Test
    public void removeChild2() throws DOMException {
        document = sampleHtmlFile();
        final Element html = document.getDocumentElement();
        final Element body = document.createElement("body");
        html.appendChild(body);
        Element elm = document.createElement("span");
        body.appendChild(elm);
        assertSame(body, elm.getParentNode());
        assertFalse(elm.hasChildNodes());
        final Text text = document.createTextNode("foo");
        elm.appendChild(text);
        assertTrue(elm.hasChildNodes());
        final Text text2 = document.createTextNode("bar");
        body.appendChild(text2);
        assertSame(body, text2.getParentNode());
        final Element div = document.createElement("div");
        div.appendChild(document.createTextNode("inside div"));
        body.appendChild(div);
        assertSame(body, div.getParentNode());
        final Element p = document.createElement("p");
        p.appendChild(document.createTextNode("inside p"));
        body.appendChild(p);
        assertSame(body, p.getParentNode());
        assertSame(elm.getNextSibling(), text2);
        assertSame(text2.getNextSibling(), div);
        assertSame(div.getNextSibling(), p);
        assertNull(p.getNextSibling());
        assertSame(elm.getNextElementSibling(), div);
        assertSame(text2.getNextElementSibling(), div);
        assertSame(div.getNextElementSibling(), p);
        assertNull(p.getNextElementSibling());
        assertSame(elm, body.getFirstChild());
        assertSame(elm, body.getFirstElementChild());
        assertSame(p, body.getLastChild());
        assertSame(p, body.getLastElementChild());
        //
        HTMLCollection listspan = body.getElementsByTagName("span");
        HTMLCollection listdiv = body.getElementsByTagName("div");
        HTMLCollection listp = body.getElementsByTagName("p");
        assertEquals(1, listspan.getLength());
        assertEquals(1, listdiv.getLength());
        assertEquals(1, listp.getLength());
        //
        assertSame(p.getPreviousSibling(), div);
        assertSame(p.getPreviousElementSibling(), div);
        assertSame(div.getPreviousSibling(), text2);
        assertSame(div.getPreviousElementSibling(), elm);
        assertSame(text2.getPreviousSibling(), elm);
        assertSame(text2.getPreviousElementSibling(), elm);
        assertNull(elm.getPreviousSibling());
        assertNull(elm.getPreviousElementSibling());
        assertEquals(4, body.getChildNodes().getLength());
        assertSame(elm, body.getChildNodes().item(0));
        assertSame(text2, body.getChildNodes().item(1));
        assertSame(div, body.getChildNodes().item(2));
        //
        body.removeChild(div);
        assertTrue(body.hasChildNodes());
        assertNull(div.getParentNode());
        assertNull(div.getNextSibling());
        assertNull(div.getPreviousSibling());
        assertNull(div.getNextElementSibling());
        assertNull(div.getPreviousSibling());
        assertNull(div.getPreviousElementSibling());
        assertSame(elm.getNextSibling(), text2);
        assertSame(text2.getNextSibling(), p);
        assertNull(p.getNextSibling());
        assertSame(elm.getNextElementSibling(), p);
        assertSame(text2.getNextElementSibling(), p);
        assertNull(p.getNextElementSibling());

        listspan = body.getElementsByTagName("span");
        listdiv = body.getElementsByTagName("div");
        listp = body.getElementsByTagName("p");

        assertEquals(1, listspan.getLength());
        assertEquals(0, listdiv.getLength());
        assertEquals(1, listp.getLength());
        assertSame(elm, body.getFirstChild());
        assertSame(p, body.getLastChild());
        assertEquals(3, body.getChildNodes().getLength());
        assertSame(elm, body.getChildNodes().item(0));
        assertSame(p, body.getChildNodes().item(2));
        //
        elm = (Element) body.removeChild(elm);
        assertTrue(body.hasChildNodes());
        assertNull(elm.getParentNode());
        assertNull(elm.getNextSibling());
        assertNull(elm.getPreviousSibling());
        assertNull(elm.getNextElementSibling());
        assertNull(elm.getPreviousSibling());
        assertNull(elm.getPreviousElementSibling());
        assertSame(text2.getNextSibling(), p);
        assertNull(p.getNextSibling());
        assertSame(text2, p.getPreviousSibling());
        assertSame(text2.getNextElementSibling(), p);
        assertNull(p.getNextElementSibling());
        assertNull(p.getPreviousElementSibling());

        listspan = body.getElementsByTagName("span");
        listdiv = body.getElementsByTagName("div");
        listp = body.getElementsByTagName("p");

        assertEquals(0, listspan.getLength());
        assertEquals(0, listdiv.getLength());
        assertEquals(1, listp.getLength());
        assertSame(text2, body.getFirstChild());
        assertSame(p, body.getLastChild());
        assertSame(p, body.getFirstElementChild());
        assertSame(p, body.getLastElementChild());
        assertEquals(2, body.getChildNodes().getLength());
        assertSame(text2, body.getChildNodes().item(0));
        assertSame(p, body.getChildNodes().item(1));
        //
        body.removeChild(text2);
        assertNull(text2.getParentNode());
        assertNull(text2.getNextSibling());
        assertNull(text2.getPreviousSibling());
        assertNull(text2.getNextElementSibling());
        assertNull(text2.getPreviousSibling());
        assertNull(text2.getPreviousElementSibling());
        assertNull(p.getNextElementSibling());
        assertNull(p.getPreviousElementSibling());
        assertNull(p.getNextSibling());
        assertNull(p.getPreviousSibling());

        listspan = body.getElementsByTagName("span");
        listdiv = body.getElementsByTagName("div");
        listp = body.getElementsByTagName("p");

        assertEquals(0, listspan.getLength());
        assertEquals(0, listdiv.getLength());
        assertEquals(1, listp.getLength());
        assertSame(p, body.getFirstChild());
        assertSame(p, body.getLastChild());
        assertSame(p, body.getFirstElementChild());
        assertSame(p, body.getLastElementChild());
        assertEquals(1, body.getChildNodes().getLength());
        assertSame(p, body.getChildNodes().item(0));
        //
        body.removeChild(p);
        assertFalse(body.hasChildNodes());
        assertEquals(0, body.getChildNodes().getLength());
        assertNull(body.getFirstChild());
        assertNull(body.getLastChild());
        assertNull(body.getFirstElementChild());
        assertNull(body.getLastElementChild());
        assertNull(p.getParentNode());
        assertNull(p.getNextSibling());
        assertNull(p.getPreviousSibling());
        assertNull(p.getNextElementSibling());
        assertNull(p.getPreviousSibling());
        assertNull(p.getPreviousElementSibling());
    }

    @Test
    public void replaceChild() throws DOMException {
        document = sampleHtmlFile();
        final Element html = document.getDocumentElement();
        final Element body = document.createElement("body");
        body.setAttribute("id", "body1");
        html.appendChild(body);
        final Element body2 = document.createElement("body");
        body2.setAttribute("id", "body2");
        final Element elm = (Element) html.replaceChild(body2, body);
        assertEquals(body, elm);
        assertSame(html, body2.getParentNode());
        assertNotNull(elm.getParentNode());
        assertNotNull(body.getParentNode());
        assertNull(body.getNextSibling());
        assertNull(body.getPreviousSibling());
        assertNull(body.getNextElementSibling());
        assertNull(body.getPreviousElementSibling());
        final Text foo1 = document.createTextNode("foo1");
        body2.appendChild(foo1);
        final Text foo2 = document.createTextNode("foo2");
        assertNull(foo2.getParentNode());
        final Text text = (Text) body2.replaceChild(foo2, foo1);
        assertSame(foo1, text);
        assertEquals("foo1", text.getTextContent());
        assertEquals(body2, foo2.getParentNode());
        assertNotNull(text.getParentNode());
    }

    @Test
    public void replaceChild2() throws DOMException {
        document = sampleHtmlFile();
        final Element html = document.getDocumentElement();
        final Element body = document.createElement("body");
        html.appendChild(body);
        final Element span = document.createElement("span");
        body.appendChild(span);
        assertSame(body, span.getParentNode());
        assertFalse(span.hasChildNodes());
        final Text text = document.createTextNode("foo");
        span.appendChild(text);
        assertTrue(span.hasChildNodes());
        final Text text2 = document.createTextNode("bar");
        body.appendChild(text2);
        assertSame(body, text2.getParentNode());
        final Element div = document.createElement("div");
        div.appendChild(document.createTextNode("inside div"));
        body.appendChild(div);
        assertSame(body, div.getParentNode());
        final Element p = document.createElement("p");
        p.appendChild(document.createTextNode("inside p"));
        body.appendChild(p);
        //
        final HTMLCollection listspan = body.getElementsByTagName("span");
        final HTMLCollection listdiv = body.getElementsByTagName("div");
        final HTMLCollection listp = body.getElementsByTagName("p");
        assertEquals(1, listspan.getLength());
        assertEquals(1, listdiv.getLength());
        assertEquals(1, listp.getLength());
        //
        final Element div2 = document.createElement("div");
        div2.setAttribute("id", "div2");
        final Element elm = (Element) body.replaceChild(div2, div);
        assertSame(div, elm);
        assertSame(body, div2.getParentNode());
        assertNotNull(elm.getParentNode());
        assertNull(elm.getNextSibling());
        assertNull(elm.getPreviousSibling());
        assertNull(elm.getNextElementSibling());
        assertNull(elm.getPreviousElementSibling());
        //
        assertNull(span.getPreviousSibling());
        assertNull(span.getPreviousElementSibling());
        assertSame(span.getNextSibling(), text2);
        assertSame(text2.getNextSibling(), div2);
        assertSame(div2.getNextSibling(), p);
        assertNull(p.getNextSibling());
        assertSame(span.getNextElementSibling(), div2);
        assertSame(text2.getNextElementSibling(), div2);
        assertSame(div2.getNextElementSibling(), p);
        assertNull(p.getNextElementSibling());
        assertSame(span, body.getFirstChild());
        assertSame(span, body.getFirstElementChild());
        assertSame(p, body.getLastChild());
        assertSame(p, body.getLastElementChild());
        assertEquals("div2", div2.getAttribute("id"));
        assertEquals(1, listspan.getLength());
        assertEquals(1, listdiv.getLength());
        assertEquals(1, listp.getLength());
        //
        assertEquals(4, body.getChildNodes().getLength());
        assertSame(span, body.getChildNodes().item(0));
        assertSame(text2, body.getChildNodes().item(1));
        assertSame(div2, body.getChildNodes().item(2));
        assertSame(p, body.getChildNodes().item(3));
        assertEquals(3, body.getChildren().getLength());
        assertSame(span, body.getChildren().item(0));
        assertSame(div2, body.getChildren().item(1));
        assertSame(p, body.getChildren().item(2));
    }

    @Test
    public void replaceByMyself() throws DOMException {
        document = sampleHtmlFile();
        final Element html = document.getDocumentElement();
        final Element elm1 = document.createElement("div");
        html.appendChild(elm1);
        final Element elm2 = document.createElement("p");
        html.appendChild(elm2);
        assertSame(elm1, html.replaceChild(elm1, elm1));
        assertSame(elm1, elm2.getPreviousSibling());
        assertSame(elm1, elm2.getPreviousElementSibling());
        assertSame(elm2, elm1.getNextSibling());
        assertSame(elm2, elm1.getNextElementSibling());
        assertEquals(4, html.getChildNodes().getLength());
        assertSame(elm2, html.replaceChild(elm2, elm2));
        assertSame(elm1, elm2.getPreviousSibling());
        assertSame(elm1, elm2.getPreviousElementSibling());
        assertSame(elm2, elm1.getNextSibling());
        assertSame(elm2, elm1.getNextElementSibling());
    }

    @Test
    public void replaceChildDF() throws DOMException {
        document = sampleHtmlFile();
        final Element html = document.getDocumentElement();
        final Element body = document.createElement("body");
        html.appendChild(body);
        final Element elm1 = document.createElement("p");
        body.appendChild(elm1);
        final Element elm2 = document.createElement("div");
        body.insertBefore(elm2, elm1);
        final Element elm3 = document.createElement("span");
        body.insertBefore(elm3, elm1);
        assertEquals(3, body.getChildNodes().getLength());
        final DocumentFragment fragment = createDocumentFragment();
        body.replaceChild(fragment, elm3);
        assertEquals(3, body.getChildNodes().getLength());
        assertEquals("P", body.getChildNodes().item(2).getNodeName());
        assertNotNull(fragment.getFirstChild());
        assertNotNull(fragment.getLastChild());
        assertNotNull(fragment.getParentNode());
    }

    @Test
    public void cloneNode() {
        document = sampleHtmlFile();
        final Element elm = document.createElement("p");
        elm.setAttribute("foo", "bar");
        final Text foo = document.createTextNode("foo");
        elm.appendChild(foo);
        final Element elmc = (Element) elm.cloneNode(true);
        assertEquals(elm.getTagName(), elmc.getTagName());
        assertEquals(elm.getAttribute("foo"), elmc.getAttribute("foo"));
        assertEquals(elm.getChildNodes().getLength(), elmc.getChildNodes().getLength());
        assertEquals(elm.getChildNodes().item(0).getNodeValue(), elmc.getChildNodes().item(0).getNodeValue());
    }

}