package org.nate.internal.jsoup;
import static java.util.Arrays.asList;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.nate.testutil.WhiteSpaceIgnoringXmlMatcher.matchesXmlIgnoringWhiteSpace;
import java.io.ByteArrayInputStream;
import java.util.List;
import org.junit.Test;
import org.nate.encoder.NateDocument;
import org.nate.encoder.NateNode;
public class JsoupBackedNateElementTest {
@Test
public void shouldFindDesiredElements() throws Exception {
NateNode element = elementFor("<div><p>apple</p> hello <p>banana</p></div>");
List<NateNode> elements = element.find("p");
assertThat("Unexpected size for: " + elements, elements.size(), is(2));
assertThat(elements.get(0).render(), matchesXmlIgnoringWhiteSpace("<p>apple</p>"));
assertThat(elements.get(1).render(), matchesXmlIgnoringWhiteSpace("<p>banana</p>"));
}
@Test
public void shouldFindNoElementsWhenNoneMatch() throws Exception {
NateNode element = elementFor("<div><p>apple</p> hello <p>banana</p></div>");
List<NateNode> elements = element.find("p.foo");
assertThat("Unexpected size for: " + elements, elements.size(), is(0));
}
@Test
public void shouldSetTextContentWithSuppliedValue() throws Exception {
NateNode element = elementFor("<span><p>apple</p></span>");
element.setTextContent("a & b");
assertThat(element.render(), matchesXmlIgnoringWhiteSpace("<span>a & b</span>"));
}
@Test
public void shouldSetAttributeWithSuppliedValue() throws Exception {
NateNode element = elementFor("<span><p>apple</p></span>");
element.setAttribute("foo", "a & \" b");
assertThat(element.render(), matchesXmlIgnoringWhiteSpace("<span foo='a & " b'><p>apple</p></span>"));
}
@Test
public void shouldReturnCopyWhenRequested() throws Exception {
NateNode original = elementFor("<span>apple</span>");
NateNode copy = original.copy();
copy.setTextContent("banana");
assertThat(copy.render(), matchesXmlIgnoringWhiteSpace("<span>banana</span>"));
assertThat(original.render(), matchesXmlIgnoringWhiteSpace("<span>apple</span>"));
}
@Test
public void shouldReplaceChildren() throws Exception {
NateNode element = elementFor("<span><p>apple</p></span>");
NateDocument newChildren = createDocumentFragment("a <b>banana</b> or two");
element.replaceChildren(newChildren);
assertThat(element.render(), matchesXmlIgnoringWhiteSpace("<span>a <b>banana</b> or two</span>"));
assertThat(newChildren.render(), matchesXmlIgnoringWhiteSpace("a <b>banana</b> or two"));
}
@Test
public void shouldReplaceSelfWithNewNodes() throws Exception {
NateNode document = createDocumentFragment("<section><span>apple</span></section>");
NateNode node1 = createDocumentFragment("a <b>banana</b> or two");
NateNode node2 = elementFor("<p>apple</p>");
NateNode element = document.find("span").get(0);
element.replaceWith(asList(node1, node2));
assertThat(document.render(), matchesXmlIgnoringWhiteSpace("<section> a <b>banana</b> or two <p>apple</p> </section>"));
assertThat(node1.render(), matchesXmlIgnoringWhiteSpace("a <b>banana</b> or two"));
assertThat(node2.render(), matchesXmlIgnoringWhiteSpace("<p>apple</p>"));
}
@Test
public void shouldLeaveSiblingsUntouchedWhenReplacingSelf() throws Exception {
NateNode document = createDocumentFragment("<section><span>apple</span><p>orange</p></section>");
NateNode element = document.find("span").get(0);
NateNode sibling = document.find("p").get(0);
element.replaceWith(asList((NateNode)createDocumentFragment("banana")));
sibling.setAttribute("id", "7");
assertThat(document.find("p").get(0).render(), matchesXmlIgnoringWhiteSpace("<p id='7'>orange</p>"));
}
@Test
public void shouldReplaceSelfWithNewNodesWhenNoParent() throws Exception {
NateNode document = createDocumentFragment("<span>apple</span>");
NateNode node1 = createDocumentFragment("a <b>banana</b> or two");
NateNode node2 = elementFor("<p>apple</p>");
NateNode element = document.find("span").get(0);
element.replaceWith(asList(node1, node2));
assertThat(document.render(), matchesXmlIgnoringWhiteSpace("a <b>banana</b> or two <p>apple</p>"));
assertThat(node1.render(), matchesXmlIgnoringWhiteSpace("a <b>banana</b> or two"));
assertThat(node2.render(), matchesXmlIgnoringWhiteSpace("<p>apple</p>"));
}
@Test(expected=IllegalStateException.class)
public void shouldBecomeInvalidAfterReplacementOfSelf() throws Exception {
NateNode element = elementFor("<div>apple</div>");
element.replaceWith(asList((NateNode) elementFor("<p>banana</p>")));
// This should throw an exception
element.setTextContent("peach");
}
private NateDocument createDocumentFragment(String input) {
JsoupBackedNateDocument fullDocument = new JsoupBackedNateDocumentFactory()
.createFromHtmlDocument(new ByteArrayInputStream(input.getBytes()));
return fullDocument.copyContentOf("body");
}
private JsoupBackedNateElement elementFor(String input) {
NateDocument document = createDocumentFragment("<wrapper>" + input + "</wrapper>");
return (JsoupBackedNateElement) document.find("wrapper > *").get(0);
}
}