// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package jodd.lagarto.dom;
import jodd.io.FileUtil;
import jodd.util.StringUtil;
import org.junit.Before;
import org.junit.Test;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import static org.junit.Assert.*;
public class DomTreeTest {
protected String testDataRoot;
@Before
public void setUp() throws Exception {
if (testDataRoot != null) {
return;
}
URL data = NodeSelectorTest.class.getResource("test");
testDataRoot = data.getFile();
}
@Test
public void testSpecialCases() {
Document document = new Document();
Element html = new Element(document, "html");
document.addChild(html);
assertEquals(0, html.getChildNodesCount());
assertNull(html.getChild(0));
assertNull(html.getChild(1000));
assertEquals(0, html.getChildNodes().length);
assertNull(html.getFirstChild());
assertNull(html.getFirstChildElement());
assertNull(html.getFirstChildElement("h1"));
assertNull(html.getLastChild());
assertNull(html.getLastChildElement());
assertNull(html.getLastChildElement("h1"));
assertEquals(0, html.getSiblingIndex());
assertEquals(0, html.getSiblingElementIndex());
assertEquals(0, html.getSiblingNameIndex());
assertTrue(document.check());
}
@Test
public void testDetach() {
Document document = new Document();
Element html = new Element(document, "html");
document.addChild(html);
Element div1 = new Element(document, "div");
html.addChild(div1);
Element div2 = new Element(document, "div");
div1.addChild(div2);
div1.detachFromParent();
assertEquals(0, html.getChildNodesCount());
assertNull(div1.getParentNode());
assertTrue(document.check());
}
@Test
public void testInsertRemoveDeepLevel() {
Document document = new Document();
Element html = new Element(document, "html");
document.addChild(html);
Element div1 = new Element(document, "div");
html.addChild(div1);
Element div2 = new Element(document, "div");
html.addChild(div2);
Element div3 = new Element(document, "div");
html.addChild(div3);
assertEquals(3, html.getChildNodesCount());
assertEquals(3, html.getChildElementsCount());
assertEquals(3, html.getChildElementsCount("div"));
assertEquals(div2, html.removeChild(1));
assertEquals(2, html.getChildNodesCount());
assertEquals(2, html.getChildElementsCount());
assertEquals(2, html.getChildElementsCount("div"));
html.insertAfter(div2, div1);
assertEquals(3, html.getChildNodesCount());
assertEquals(3, html.getChildElementsCount());
assertEquals(3, html.getChildElementsCount("div"));
Node[] node = html.getChildNodes();
assertEquals(div1, node[0]);
assertEquals(div2, node[1]);
assertEquals(div3, node[2]);
html.removeChild(1);
assertEquals(2, html.getChildNodesCount());
assertEquals(2, html.getChildElementsCount());
assertEquals(2, html.getChildElementsCount("div"));
html.insertBefore(div2, div3);
assertEquals(3, html.getChildNodesCount());
assertEquals(3, html.getChildElementsCount());
assertEquals(3, html.getChildElementsCount("div"));
node = html.getChildNodes();
assertEquals(div1, node[0]);
assertEquals(div2, node[1]);
assertEquals(div3, node[2]);
html.removeChild(div2);
node = html.getChildNodes();
assertEquals(div1, node[0]);
assertEquals(div3, node[1]);
html.insertAfter(div2, div3);
html.insertBefore(div2, div1);
node = html.getChildNodes();
assertEquals(div2, node[0]);
assertEquals(div1, node[1]);
assertEquals(div3, node[2]);
assertFalse(div1.hasChildNodes());
assertTrue(html.hasChildNodes());
assertTrue(document.check());
}
@Test
public void testAttributes() {
Document document = new Document();
Element node = new Element(document, "div");
assertFalse(node.hasAttributes());
assertFalse(node.hasAttribute("id"));
assertNull(node.getAttribute("id"));
node.setAttribute("id", "jodd");
assertTrue(node.hasAttributes());
assertTrue(node.hasAttribute("id"));
assertEquals("jodd", node.getAttribute("id"));
node.setAttribute("foo");
assertTrue(node.hasAttribute("foo"));
assertNull(node.getAttribute("foo"));
assertFalse(node.isAttributeContaining("class", "one"));
node.setAttribute("class", " one two three ");
assertTrue(node.isAttributeContaining("class", "two"));
assertTrue(node.isAttributeContaining("class", "three"));
assertEquals(3, node.getAttributesCount());
}
@Test
public void testChildren() {
Document document = new Document();
Element node = new Element(document, "div");
Text textHello = new Text(document, "hello");
node.addChild(textHello);
Element em = new Element(document, "em");
node.addChild(em);
Text textJodd = new Text(document, "jodd");
em.addChild(textJodd);
Text textHey = new Text(document, "!");
node.addChild(textHey);
assertEquals(3, node.getChildNodesCount());
assertEquals(1, node.getChildElementsCount());
assertEquals(1, node.getChildElementsCount("em"));
Element b = new Element(document, "b");
node.addChild(b);
Text textJodd2 = new Text(document, "fwk");
b.addChild(textJodd2);
assertEquals(4, node.getChildNodesCount());
assertEquals(2, node.getChildElementsCount());
assertEquals(1, node.getChildElementsCount("em"));
assertEquals(1, node.getChildElementsCount("b"));
assertEquals(b, em.getNextSiblingElement());
assertNull(em.getNextSiblingName());
assertNull(em.getPreviousSiblingElement());
assertNull(em.getPreviousSiblingName());
assertEquals(em, b.getPreviousSiblingElement());
assertNull(b.getNextSiblingName());
assertNull(b.getNextSiblingElement());
assertNull(b.getPreviousSiblingName());
assertTrue(node.check());
}
@Test
public void testCssPath() {
Document document = new Document();
Element html = new Element(document, "html");
document.addChild(html);
Element div1 = new Element(document, "div");
div1.setAttribute("id", "one");
html.addChild(div1);
Element div2 = new Element(document, "div");
div1.addChild(div2);
assertEquals("html div#one div", div2.getCssPath());
assertEquals("html div#one", div1.getCssPath());
assertTrue(document.check());
}
@Test
public void testToWrite() throws IOException {
Document document = new LagartoDOMBuilder().parse("<html><body><form><input><input><img></form></body></html>");
String innerHtml = document.getHtml();
assertEquals("<html><body><form><input><input><img></form></body></html>", innerHtml);
assertTrue(document.check());
File file = new File(testDataRoot, "jodd.html");
String html = FileUtil.readString(file);
html = StringUtil.replace(html, " />", "/>");
html = StringUtil.replace(html, "'", "");
document = new LagartoDOMBuilder().enableXhtmlMode().parse(html);
innerHtml = document.getHtml();
innerHtml = StringUtil.replace(innerHtml, "»", "»");
innerHtml = StringUtil.replace(innerHtml, " ", " ");
innerHtml = StringUtil.replace(innerHtml, "·", "·");
assertEquals(html, innerHtml);
assertTrue(document.check());
file = new File(testDataRoot, "Twitter.html");
html = FileUtil.readString(file);
html = StringUtil.replace(html, " />", "/>");
html = StringUtil.replace(html, "\" >", "\">");
html = StringUtil.replace(html, "'", "");
html = StringUtil.replace(html, " ", " ");
LagartoDOMBuilder builder = new LagartoDOMBuilder();
builder.getConfig().setSelfCloseVoidTags(true); // use self-closing tags!
builder.getConfig().setEnableConditionalComments(true).setCondCommentIEVersion(6);
document = builder.parse(html);
innerHtml = document.getHtml();
innerHtml = StringUtil.replace(innerHtml, "»", "»");
innerHtml = StringUtil.replace(innerHtml, " ", " ");
innerHtml = StringUtil.replace(innerHtml, "·", "·");
innerHtml = StringUtil.replace(innerHtml, "’", "’");
innerHtml = StringUtil.replace(innerHtml, "©", "©");
html = StringUtil.replace(html, "<!--[if lte IE 6]>", "");
html = StringUtil.replace(html, "<![endif]-->", "");
assertEquals(html, innerHtml);
assertTrue(document.check());
file = new File(testDataRoot, "Yahoo!.html");
html = FileUtil.readString(file);
html = StringUtil.replace(html, " />", "/>");
html = StringUtil.replace(html, "\" >", "\">");
html = StringUtil.replace(html, "'", "");
document = new LagartoDOMBuilder().parse(html);
NodeSelector nodeSelector = new NodeSelector(document);
Element div = (Element) nodeSelector.selectFirst("div.ysites-col");
Element h2 = (Element) div.getFirstChild();
assertEquals(2, h2.getAttributesCount());
assertEquals("y-ftr-txt-hdr ", h2.getAttribute("class"));
assertTrue(h2.isAttributeContaining("class", "y-ftr-txt-hdr"));
assertTrue(h2.hasAttribute("\""));
assertTrue(document.check());
}
@Test
public void testBr() throws IOException {
Document document = new LagartoDOMBuilder().parse("<div><br>some content <br>Some more</div>");
String innerHtml = document.getHtml();
assertEquals("<div><br>some content <br>Some more</div>", innerHtml);
assertTrue(document.check());
document = new LagartoDOMBuilder().parse("<br>some content <br>Some more");
innerHtml = document.getHtml();
assertEquals("<br>some content <br>Some more", innerHtml);
assertTrue(document.check());
}
@Test
public void testReindexOne() {
Document document = new Document();
Element one = new Element(document, "one");
document.addChild(one);
assertEquals(1, document.childElementNodesCount);
assertEquals(0, one.siblingElementIndex);
Element two = new Element(document, "two");
document.addChild(two);
assertEquals(2, document.childElementNodesCount);
assertEquals(0, one.siblingElementIndex);
assertEquals(1, two.siblingElementIndex);
Text three = new Text(document, "xxx");
document.addChild(three);
Element four = new Element(document, "four");
document.addChild(four);
assertEquals(3, document.childElementNodesCount);
assertEquals(0, one.siblingElementIndex);
assertEquals(1, two.siblingElementIndex);
assertEquals(2, four.siblingElementIndex);
}
@Test
public void testHasVsGet333() {
Document document = new Document();
Element one = new Element(document, "one");
document.addChild(one);
one.setAttribute("a1", "v1");
assertEquals("v1", one.getAttribute("a1"));
assertEquals("v1", one.getAttribute("A1"));
assertTrue(one.hasAttribute("a1"));
assertTrue(one.hasAttribute("A1"));
}
}