package com.googlecode.totallylazy.xml;
import com.googlecode.totallylazy.Sequence;
import com.googlecode.totallylazy.functions.TimeReport;
import com.googlecode.totallylazy.matchers.NumberMatcher;
import org.hamcrest.CoreMatchers;
import org.junit.Ignore;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import java.util.Iterator;
import java.util.NoSuchElementException;
import static com.googlecode.totallylazy.Sequences.repeat;
import static com.googlecode.totallylazy.Sequences.sequence;
import static com.googlecode.totallylazy.matchers.IterableMatcher.hasExactly;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.fail;
public class XmlTest {
@Test
public void shouldSupportRealWorldNamespacesAndComplexQueries() throws Exception {
Document bt = Xml.document("<?xml version=\"1.0\"?>\n" +
"<or:OrderStatusUpdate xmlns:gea=\"urn:uk.org.telcob2b/tML/Fulfilment/GEA-v16-0\" xmlns:odr=\"urn:uk.org.telcob2b/tML/BT-OrderResponse-v16-0\" xmlns:or=\"urn:com.openreach.Fulfilment2-v16-0\" xmlns:utcc=\"urn:uk.org.telcob2b/tML/ukt-CommonComponents-v16-0\" xmlns=\"\">\n" +
" <odr:OrderResponse>\n" +
" <utcc:RespondedOrderLine>\n" +
" <utcc:OrderLineMessageInfo>\n" +
" <utcc:MessageInfo>\n" +
" <utcc:CompletionCode>510</utcc:CompletionCode>\n" +
" </utcc:MessageInfo>\n" +
" </utcc:OrderLineMessageInfo>\n" +
" </utcc:RespondedOrderLine>\n" +
" </odr:OrderResponse>\n" +
"</or:OrderStatusUpdate>\n");
assertThat(Xml.selectNodes(bt, "tl:trim-and-join(//MessageInfo/CompletionCode, \"\\n\")").size(), is(1));
}
@Test
@Ignore("manual test")
public void xpathIsPrettyFast() throws Exception {
final Document document = example();
TimeReport report = TimeReport.time(1000, () -> {
return Xml.selectNodes(document, "//meta/@content");
});
System.out.println(report);
}
@Test
public void canLoadHtml() throws Exception {
Document document = example();
assertThat(Xml.selectNodes(document, "//meta/@content").map(Xml.contents()), hasExactly("Foo", "Bar"));
assertThat(Xml.selectContents(document, "descendant::boo"), is("far"));
assertThat(Xml.selectContents(document, "descendant::foo"), is("baz"));
}
private Document example() {
return Xml.document(
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML+RDFa 1.0//EN\" \"http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd\">\n" +
"<xh:html xmlns:xh=\"http://www.w3.org/1999/xhtml\" xmlns:og=\"http://opengraphprotocol.org/schema/\" xml:lang=\"en-GB\" xmlns=\"\">\n" +
"<xh:head><xh:meta content=\"Foo\"/><xh:meta content=\"Bar\"/></xh:head>" +
"<foo>baz</foo>" +
"<og:boo>far</og:boo>" +
"</xh:html>");
}
@Test
public void canEscapeXml() throws Exception {
assertThat(Xml.escape("& < > ' \" " + new Character((char) 0x80)), is("& < > ' " "));
}
@Test
public void doesNotTruncateString() throws Exception {
String testString = longStringWithoutEncodedChars();
assertThat(Xml.escape(testString), is(testString));
}
private String longStringWithoutEncodedChars() {
return repeat("A").take(100).toString("");
}
@Test
public void supportsXPathExpressionsWithFunctionsThatReturnStrings() throws Exception{
Document document = Xml.document("<root><child type=\"name\" value=\"bob\"/></root>");
String value = Xml.selectContents(document, "concat(//child/@type, ':', //child/@value)");
assertThat(value, is("name:bob"));
}
@Test
public void supportsReturningANumber() throws Exception{
Document document = Xml.document("<root><child type=\"name\" value=\"bob\"/></root>");
Number value = Xml.selectNumber(document, "count(//child)");
assertThat(value, NumberMatcher.is(1));
}
@Test
public void supportsReturningABoolean() throws Exception{
Document document = Xml.document("<root><child type=\"name\" value=\"bob\"/></root>");
boolean value = Xml.matches(document, "count(//child) = 1");
assertThat(value, is(true));
}
@Test
public void supportsUTF16() throws Exception {
Document document = Xml.document("<?xml version=\"1.0\" encoding=\"UTF-16\" standalone=\"no\"?>\n"+
"<root><child><name>bob</name></child></root>");
Number value = Xml.selectNumber(document, "count(//child)");
assertThat(value, NumberMatcher.is(1));
}
@Test
public void nextOnNodeIteratorWorks() {
Document document = Xml.document("<?xml version=\"1.0\" encoding=\"UTF-16\" standalone=\"no\"?>\n"+
"<root></root>");
Iterator<Node> value = Xml.selectNodes(document, "zerolength").iterator();
try {
assertThat(value.next(), not(nullValue()));
fail("Expected exception");
}catch (NoSuchElementException e){
// Expected
}
}
}