package com.googlecode.totallylazy.xml.streaming; import com.googlecode.totallylazy.Sequence; import org.junit.Test; import org.w3c.dom.Document; import org.w3c.dom.Node; import static com.googlecode.totallylazy.Assert.assertThat; import static com.googlecode.totallylazy.predicates.Predicates.is; import static com.googlecode.totallylazy.xml.Xml.document; import static com.googlecode.totallylazy.xml.Xml.selectNodes; import static com.googlecode.totallylazy.xml.streaming.XPath.attribute; import static com.googlecode.totallylazy.xml.streaming.XPath.child; import static com.googlecode.totallylazy.xml.streaming.XPath.descendant; import static com.googlecode.totallylazy.xml.streaming.XPath.name; import static com.googlecode.totallylazy.xml.streaming.XPath.text; import static com.googlecode.totallylazy.xml.streaming.XPath.xpath; import static com.googlecode.totallylazy.xml.streaming.Xml.contexts; public class ContextTest { @Test public void unfilteredHasCorrectNumberOfContexts() throws Exception { String xml = "<stream><user><first>Dan & Bod</first><dob>1977</dob></user><user><first>Jason</first><dob>1978</dob></user></stream>"; Sequence<Context> locations = contexts(xml); org.junit.Assert.assertEquals(locations.toString("\n"), "<stream>\n" + "<stream>/<user>\n" + "<stream>/<user>/<first>\n" + "<stream>/<user>/<first>/Dan & Bod\n" + "<stream>/<user>/<dob>\n" + "<stream>/<user>/<dob>/1977\n" + "<stream>/<user>\n" + "<stream>/<user>/<first>\n" + "<stream>/<user>/<first>/Jason\n" + "<stream>/<user>/<dob>\n" + "<stream>/<user>/<dob>/1978"); } @Test public void unfilteredStillWorksEvenWhenTextHasNestedElement() throws Exception { String xml = "<stream>Hello <b>Dan</b> Bodart</stream>"; Sequence<Context> locations = contexts(xml); org.junit.Assert.assertEquals(locations.toString("\n"), "<stream>\n" + "<stream>/Hello \n" + "<stream>/<b>\n" + "<stream>/<b>/Dan\n" + "<stream>/ Bodart"); } @Test public void shouldSupportChild() throws Exception { String xml = "<stream><user><first>Dan & Bod</first><dob>1977</dob></user><user><first>Jason</first><dob>1978</dob></user></stream>"; Document document = document(xml); Sequence<Node> nodes = selectNodes(document, "child::*"); Sequence<Context> locations = contexts(xml).filter(xpath(child(name("*")))); assertThat(locations.size(), is(nodes.size())); Node root = nodes.head(); Context rootContext = locations.head(); assertThat(rootContext.name(), is(root.getNodeName())); } @Test public void shouldSupportDescendant() throws Exception { String xml = "<stream><user><first>Dan & Bod</first><dob>1977</dob></user><user><first>Jason</first><dob>1978</dob></user></stream>"; Document document = document(xml); Sequence<Node> nodes = selectNodes(document, "descendant::*"); Sequence<Context> locations = contexts(xml).filter(xpath(descendant(name("*")))); assertThat(locations.size(), is(nodes.size())); Node root = nodes.head(); Context rootContext = locations.head(); assertThat(rootContext.name(), is(root.getNodeName())); } @Test public void shouldSupportDescendantWithNames() throws Exception { String xml = "<stream><user><first>Dan & Bod</first><dob>1977</dob></user><user><first>Jason</first><dob>1978</dob></user></stream>"; Document document = document(xml); Sequence<Node> nodes = selectNodes(document, "descendant::user"); Sequence<Context> locations = contexts(xml).filter(xpath(descendant(name("user")))); assertThat(locations.size(), is(nodes.size())); Node root = nodes.head(); Context rootContext = locations.head(); assertThat(rootContext.name(), is(root.getNodeName())); } @Test public void shouldSupportAttributes() throws Exception { String xml = "<stream><user first='Dan'></user><user first='Jason'></user></stream>"; Document document = document(xml); Sequence<Node> nodes = selectNodes(document, "descendant::user[@first='Dan']"); Sequence<Context> locations = contexts(xml). filter(xpath(descendant(name("user").and(attribute("first", is("Dan")))))); assertThat(locations.size(), is(nodes.size())); Node root = nodes.head(); Context rootContext = locations.head(); assertThat(rootContext.name(), is(root.getNodeName())); } @Test public void shouldSupportTextNodes() throws Exception { String xml = "<stream><user><first>Dan & Bod</first><dob>1977</dob></user><user><first>Jason</first><dob>1978</dob></user></stream>"; Document document = document(xml); Sequence<Node> nodes = selectNodes(document, "descendant::text()"); Sequence<Context> locations = contexts(xml).filter(xpath(descendant(text()))); assertThat(locations.size(), is(nodes.size())); Node root = nodes.head(); Context rootContext = locations.head(); assertThat(rootContext.text(), is(root.getTextContent())); } @Test public void canGetTextOfElement() throws Exception { String xml = "<stream><user><first>Dan & Bod</first><dob>1977</dob></user><user><first>Jason</first><dob>1978</dob></user></stream>"; Document document = document(xml); Sequence<Node> nodes = selectNodes(document, "descendant::user"); Sequence<Context> locations = contexts(xml).filter(xpath(descendant(name("user")))); assertThat(locations.size(), is(nodes.size())); Node root = nodes.head(); Context rootContext = locations.head(); assertThat(rootContext.text(), is(root.getTextContent())); } @Test public void canSelectTextNodes() throws Exception { String xml = "<stream>Hello <b>Dan</b> Bodart</stream>"; Document document = document(xml); Sequence<Node> nodes = selectNodes(document, "child::stream/child::text()"); Sequence<Context> all = contexts(xml); Sequence<Context> locations = all. filter(xpath(child(name("stream")), child(text()))); assertThat(locations.size(), is(nodes.size())); Node root = nodes.head(); Context rootContext = locations.head(); assertThat(rootContext.text(), is(root.getTextContent())); } @Test public void supportsRelative() throws Exception { String xml = "<stream><user><first>Dan & Bod</first><dob>1977</dob></user><user><first>Jason</first><dob>1978</dob></user></stream>"; Document document = document(xml); Sequence<Node> userNodes = selectNodes(document, "descendant::user"); Sequence<Context> usersContexts = contexts(xml). filter(xpath(descendant(name("user")))); assertThat(usersContexts.size(), is(userNodes.size())); Context danContext = usersContexts.head(); Sequence<Context> relative = danContext.relative(); assertThat(relative.toString("\n"), is("<first>\n" + "<first>/Dan & Bod\n" + "<dob>\n" + "<dob>/1977")); } @Test public void oneItemWithTwoChildren() throws Exception { String xml = "<stream><item><child/><child/></item></stream>"; Sequence<Context> locations = contexts(xml); org.junit.Assert.assertEquals(locations.toString("\n"), "<stream>\n" + "<stream>/<item>\n" + "<stream>/<item>/<child>\n" + "<stream>/<item>/<child>"); } }