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; import org.nate.exception.BadCssExpressionException; public class JsoupBackedNateDocumentFragmentTest { @Test public void shouldFindDesiredElements() throws Exception { NateDocument document = createDocumentFragment("<div><p>apple</p> hello <p>banana</p></div>"); List<NateNode> elements = document.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 shouldFindAnEmptyListWhenNothingMatches() throws Exception { NateDocument document = createDocumentFragment("<div><p>apple</p></div>"); List<NateNode> elements = document.find("a"); assertThat("Unexpected size for: " + elements, elements.size(), is(0)); } @Test(expected=BadCssExpressionException.class) public void shouldThrowBadCssExressionExceptionWhenInvalidCssIsSupplied() throws Exception { createDocumentFragment("<div/>").find("p&#*$"); } @Test public void shouldCopyDesiredElements() throws Exception { String original = "<section><div>a</div>x<div>b</div></section>"; NateDocument document = createDocumentFragment(original); NateNode copy = document.copy("div"); assertThat(copy.render(), matchesXmlIgnoringWhiteSpace("<div> a </div> <div> b </div>")); } @Test public void shouldCopyDesiredElementsDeeply() throws Exception { String original = "<section><div>a<div>b</div></div>x<div>c</div></section>"; NateDocument document = createDocumentFragment(original); NateNode copy = document.copy("div"); assertThat(copy.render(), matchesXmlIgnoringWhiteSpace("<div> a <div> b </div> </div> <div> b </div> <div> c </div>")); } @Test public void shouldLeaveOriginalUnchangedAfterCopy() throws Exception { String original = "<div> a <div> b </div> </div> x <div> c </div>"; NateDocument document = createDocumentFragment(original); document.copy("div"); assertThat(document.render(), matchesXmlIgnoringWhiteSpace(original)); } @Test public void shouldCopyNothingWhenNothingMatches() throws Exception { String original = "<section><div>a<div>b</div></div>x<div>c</div></section>"; NateDocument document = createDocumentFragment(original); NateNode copy = document.copy("div.foo"); assertThat(copy.render(), matchesXmlIgnoringWhiteSpace("")); } @Test public void shouldCopyContentOfDesiredElements() throws Exception { String original = "<section><div>a<div>b</div></div>x<div>c</div></section>"; NateDocument document = createDocumentFragment(original); NateNode copy = document.copyContentOf("div"); assertThat(copy.render(), matchesXmlIgnoringWhiteSpace("a <div> b </div>bc")); } @Test public void shouldLeaveOriginalUnchangedAfterCopyingContent() throws Exception { String original = "<section><div>a<div>b</div></div>x<div>c</div></section>"; NateDocument document = createDocumentFragment(original); document.copyContentOf("div"); assertThat(document.render(), matchesXmlIgnoringWhiteSpace(original)); } @Test public void shouldCopyContentOfNothingWhenNothingMatches() throws Exception { String original = "<section><div>a<div>b</div></div>x<div>c</div></section>"; NateDocument document = createDocumentFragment(original); NateNode copy = document.copyContentOf("div.foo"); assertThat(copy.render(), matchesXmlIgnoringWhiteSpace("")); } @Test public void shouldReturnCopyWhenRequested() throws Exception { String source = "<section><div>apple</div></section>"; NateDocument original = createDocumentFragment(source); NateNode copy = original.copy(); assertThat(copy.render(), matchesXmlIgnoringWhiteSpace(source)); NateNode div = copy.find("div").get(0); div.setAttribute("class", "foo"); assertThat(div.render(), matchesXmlIgnoringWhiteSpace("<div class='foo'>apple</div>")); assertThat(original.render(), matchesXmlIgnoringWhiteSpace(source)); } @Test public void shouldSetTextContentWithSuppliedValue() throws Exception { NateDocument document = createDocumentFragment("<div><p>apple</p>hello<p>banana</p></div>"); document.setTextContent("a & b"); assertThat(document.render(), matchesXmlIgnoringWhiteSpace("a & b")); } @Test public void shouldReplaceChildren() throws Exception { NateDocument document = createDocumentFragment("<div><p>apple</p></div>"); NateDocument newChildren = createDocumentFragment("a<b>banana</b> or two"); document.replaceChildren(newChildren); assertThat(document.render(), matchesXmlIgnoringWhiteSpace("a <b>banana</b> or two")); assertThat(newChildren.render(), matchesXmlIgnoringWhiteSpace("a <b>banana</b> or two")); } @Test public void shouldReplaceChildrenWhenNoneToStartWith() throws Exception { NateDocument document = createDocumentFragment("<div/>"); NateDocument newChildren = createDocumentFragment("a <b>banana</b> or two"); document.replaceChildren(newChildren); assertThat(document.render(), matchesXmlIgnoringWhiteSpace("a <b>banana</b> or two")); assertThat(newChildren.render(), matchesXmlIgnoringWhiteSpace("a <b>banana</b> or two")); } @Test public void shouldReplaceSelfWithNewNodes() throws Exception { NateNode document = createDocumentFragment("<div>apple</div>"); NateNode node1 = createDocumentFragment("a <b>banana</b> or two"); NateNode node2 = elementFor("<p>apple</p>"); document.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>")); } 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 + "</wraper>"); return (JsoupBackedNateElement) document.find("wrapper > *").get(0); } }