aboutsummaryrefslogtreecommitdiff
path: root/src/test/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2017-02-19 18:16:52 +0000
committerMichael Williamson <mike@zwobble.org>2017-02-19 19:21:02 +0000
commitb31c5a4b4ccb835a583efa33cee178e122d564de (patch)
tree2dd68868d5cc1bbeaa5283798122b4cc4e5c2b2d /src/test/java
parent2e819654db985bf8a7e7ed76e0a43dc2f46eec8d (diff)
Handle hyperlinks created with complex fields
Diffstat (limited to 'src/test/java')
-rw-r--r--src/test/java/org/zwobble/mammoth/tests/docx/BodyXmlTests.java188
-rw-r--r--src/test/java/org/zwobble/mammoth/tests/docx/DocumentMatchers.java79
2 files changed, 250 insertions, 17 deletions
diff --git a/src/test/java/org/zwobble/mammoth/tests/docx/BodyXmlTests.java b/src/test/java/org/zwobble/mammoth/tests/docx/BodyXmlTests.java
index 3f3dca8..0bbd672 100644
--- a/src/test/java/org/zwobble/mammoth/tests/docx/BodyXmlTests.java
+++ b/src/test/java/org/zwobble/mammoth/tests/docx/BodyXmlTests.java
@@ -13,7 +13,6 @@ import org.zwobble.mammoth.internal.results.InternalResult;
import org.zwobble.mammoth.internal.xml.XmlElement;
import org.zwobble.mammoth.internal.xml.XmlNode;
import org.zwobble.mammoth.internal.xml.XmlNodes;
-import org.zwobble.mammoth.tests.DeepReflectionMatcher;
import java.io.IOException;
import java.io.InputStream;
@@ -34,6 +33,7 @@ import static org.zwobble.mammoth.tests.DeepReflectionMatcher.deepEquals;
import static org.zwobble.mammoth.tests.ResultMatchers.*;
import static org.zwobble.mammoth.tests.documents.DocumentElementMakers.*;
import static org.zwobble.mammoth.tests.docx.BodyXmlReaderMakers.bodyReader;
+import static org.zwobble.mammoth.tests.docx.DocumentMatchers.*;
import static org.zwobble.mammoth.tests.docx.OfficeXmlBuilders.*;
public class BodyXmlTests {
@@ -147,6 +147,168 @@ public class BodyXmlTests {
hasNumbering(Optional.empty()));
}
+ public static class ComplexFieldsTests {
+ private static final String URI ="http://example.com";
+ private static final XmlElement BEGIN_COMPLEX_FIELD = element("w:r", list(
+ element("w:fldChar", map("w:fldCharType", "begin"))
+ ));
+ private static final XmlElement SEPARATE_COMPLEX_FIELD = element("w:r", list(
+ element("w:fldChar", map("w:fldCharType", "separate"))
+ ));
+ private static final XmlElement END_COMPLEX_FIELD = element("w:r", list(
+ element("w:fldChar", map("w:fldCharType", "end"))
+ ));
+ private static final XmlElement HYPERLINK_INSTRTEXT = element("w:instrText", list(
+ XmlNodes.text(" HYPERLINK \"" + URI + '"')
+ ));
+ private static Matcher<DocumentElement> isEmptyHyperlinkedRun() {
+ return isHyperlinkedRun(hasChildren());
+ }
+ @SafeVarargs
+ private static Matcher<DocumentElement> isHyperlinkedRun(Matcher<? super Hyperlink>... matchers) {
+ return isRun(hasChildren(
+ allOf(
+ isHyperlink(hasHref(URI)),
+ isHyperlink(matchers)
+ )
+ ));
+ }
+
+ @Test
+ public void runsInAComplexFieldForHyperlinksAreReadAsHyperlinks() {
+ XmlElement hyperlinkRunXml = runXml("this is a hyperlink");
+ XmlElement element = paragraphXml(list(
+ BEGIN_COMPLEX_FIELD,
+ HYPERLINK_INSTRTEXT,
+ SEPARATE_COMPLEX_FIELD,
+ hyperlinkRunXml,
+ END_COMPLEX_FIELD
+ ));
+ DocumentElement paragraph = readSuccess(bodyReader(), element);
+
+ assertThat(paragraph, isParagraph(hasChildren(
+ isEmptyRun(),
+ isEmptyHyperlinkedRun(),
+ isHyperlinkedRun(hasChildren(
+ isTextElement("this is a hyperlink")
+ )),
+ isEmptyRun()
+ )));
+ }
+
+ @Test
+ public void runsAfterAComplexFieldForHyperlinksAreNotReadAsHyperlinks() {
+ XmlElement afterEndXml = runXml("this will not be a hyperlink");
+ XmlElement element = paragraphXml(list(
+ BEGIN_COMPLEX_FIELD,
+ HYPERLINK_INSTRTEXT,
+ SEPARATE_COMPLEX_FIELD,
+ END_COMPLEX_FIELD,
+ afterEndXml
+ ));
+ DocumentElement paragraph = readSuccess(bodyReader(), element);
+
+ assertThat(paragraph, isParagraph(hasChildren(
+ isEmptyRun(),
+ isEmptyHyperlinkedRun(),
+ isEmptyRun(),
+ isRun(hasChildren(
+ isTextElement("this will not be a hyperlink")
+ ))
+ )));
+ }
+
+ @Test
+ public void canHandleSplitInstrTextElements() {
+ XmlElement hyperlinkRunXml = runXml("this is a hyperlink");
+ XmlElement element = paragraphXml(list(
+ BEGIN_COMPLEX_FIELD,
+ element("w:instrText", list(
+ XmlNodes.text(" HYPE")
+ )),
+ element("w:instrText", list(
+ XmlNodes.text("RLINK \"" + URI + '"')
+ )),
+ SEPARATE_COMPLEX_FIELD,
+ hyperlinkRunXml,
+ END_COMPLEX_FIELD
+ ));
+ DocumentElement paragraph = readSuccess(bodyReader(), element);
+
+ assertThat(paragraph, isParagraph(hasChildren(
+ isEmptyRun(),
+ isEmptyHyperlinkedRun(),
+ isHyperlinkedRun(hasChildren(
+ isTextElement("this is a hyperlink")
+ )),
+ isEmptyRun()
+ )));
+ }
+
+ @Test
+ public void hyperlinkIsNotEndedByEndOfNestedComplexField() {
+ XmlElement authorInstrText = element("w:instrText", list(
+ XmlNodes.text(" AUTHOR \"John Doe\"")
+ ));
+ XmlElement hyperlinkRunXml = runXml("this is a hyperlink");
+ XmlElement element = paragraphXml(list(
+ BEGIN_COMPLEX_FIELD,
+ HYPERLINK_INSTRTEXT,
+ SEPARATE_COMPLEX_FIELD,
+ BEGIN_COMPLEX_FIELD,
+ authorInstrText,
+ SEPARATE_COMPLEX_FIELD,
+ END_COMPLEX_FIELD,
+ hyperlinkRunXml,
+ END_COMPLEX_FIELD
+ ));
+ DocumentElement paragraph = readSuccess(bodyReader(), element);
+
+ assertThat(paragraph, isParagraph(hasChildren(
+ isEmptyRun(),
+ isEmptyHyperlinkedRun(),
+ isEmptyHyperlinkedRun(),
+ isEmptyHyperlinkedRun(),
+ isEmptyHyperlinkedRun(),
+ isHyperlinkedRun(hasChildren(
+ isTextElement("this is a hyperlink")
+ )),
+ isEmptyRun()
+ )));
+ }
+
+ @Test
+ public void complexFieldNestedWithinAHyperlinkComplexFieldIsWrappedWithTheHyperlink() {
+ XmlElement authorInstrText = element("w:instrText", list(
+ XmlNodes.text(" AUTHOR \"John Doe\"")
+ ));
+ XmlElement element = paragraphXml(list(
+ BEGIN_COMPLEX_FIELD,
+ HYPERLINK_INSTRTEXT,
+ SEPARATE_COMPLEX_FIELD,
+ BEGIN_COMPLEX_FIELD,
+ authorInstrText,
+ SEPARATE_COMPLEX_FIELD,
+ runXml("John Doe"),
+ END_COMPLEX_FIELD,
+ END_COMPLEX_FIELD
+ ));
+ DocumentElement paragraph = readSuccess(bodyReader(), element);
+
+ assertThat(paragraph, isParagraph(hasChildren(
+ isEmptyRun(),
+ isEmptyHyperlinkedRun(),
+ isEmptyHyperlinkedRun(),
+ isEmptyHyperlinkedRun(),
+ isHyperlinkedRun(hasChildren(
+ isTextElement("John Doe")
+ )),
+ isEmptyHyperlinkedRun(),
+ isEmptyRun()
+ )));
+ }
+ }
+
@Test
public void runHasNoStyleIfItHasNoProperties() {
XmlElement element = runXml(list());
@@ -904,11 +1066,15 @@ public class BodyXmlTests {
return paragraphXml(list());
}
- private XmlElement paragraphXml(List<XmlNode> children) {
+ private static XmlElement paragraphXml(List<XmlNode> children) {
return element("w:p", children);
}
- private XmlElement runXml(List<XmlNode> children) {
+ private static XmlElement runXml(String text) {
+ return runXml(list(textXml(text)));
+ }
+
+ private static XmlElement runXml(List<XmlNode> children) {
return element("w:r", children);
}
@@ -916,22 +1082,10 @@ public class BodyXmlTests {
return element("w:r", list(element("w:rPr", asList(children))));
}
- private XmlElement textXml(String value) {
+ private static XmlElement textXml(String value) {
return element("w:t", list(XmlNodes.text(value)));
}
- private Matcher<DocumentElement> isParagraph(Paragraph expected) {
- return new DeepReflectionMatcher<>(expected);
- }
-
- private Matcher<DocumentElement> isRun(Run expected) {
- return new DeepReflectionMatcher<>(expected);
- }
-
- private Matcher<DocumentElement> isTextElement(String value) {
- return new DeepReflectionMatcher<>(new Text(value));
- }
-
private Matcher<? super DocumentElement> hasStyle(Optional<Style> expected) {
return hasProperty("style", deepEquals(expected));
}
@@ -944,7 +1098,7 @@ public class BodyXmlTests {
return hasProperty("numbering", deepEquals(expected));
}
- private Text text(String value) {
+ private static Text text(String value) {
return new Text(value);
}
}
diff --git a/src/test/java/org/zwobble/mammoth/tests/docx/DocumentMatchers.java b/src/test/java/org/zwobble/mammoth/tests/docx/DocumentMatchers.java
new file mode 100644
index 0000000..d2718b7
--- /dev/null
+++ b/src/test/java/org/zwobble/mammoth/tests/docx/DocumentMatchers.java
@@ -0,0 +1,79 @@
+package org.zwobble.mammoth.tests.docx;
+
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeDiagnosingMatcher;
+import org.zwobble.mammoth.internal.documents.*;
+import org.zwobble.mammoth.tests.DeepReflectionMatcher;
+
+import java.util.Optional;
+
+import static java.util.Arrays.asList;
+import static org.hamcrest.Matchers.*;
+
+public class DocumentMatchers {
+ private DocumentMatchers() {}
+
+ static Matcher<DocumentElement> isParagraph(Paragraph expected) {
+ return new DeepReflectionMatcher<>(expected);
+ }
+
+ static Matcher<DocumentElement> isRun(Run expected) {
+ return new DeepReflectionMatcher<>(expected);
+ }
+
+ static Matcher<DocumentElement> isTextElement(String value) {
+ return new DeepReflectionMatcher<>(new Text(value));
+ }
+
+ @SafeVarargs
+ static Matcher<HasChildren> hasChildren(Matcher<DocumentElement>... children) {
+ Matcher<Iterable<? extends DocumentElement>> contains = children.length == 0 ? emptyIterable() : contains(asList(children));
+ return hasProperty("children", contains);
+ }
+
+ @SafeVarargs
+ static Matcher<DocumentElement> isParagraph(Matcher<? super Paragraph>... matchers) {
+ return cast(Paragraph.class, allOf(matchers));
+ }
+
+ static Matcher<DocumentElement> isEmptyRun() {
+ return isRun(hasChildren());
+ }
+
+ @SafeVarargs
+ static Matcher<DocumentElement> isRun(Matcher<? super Run>... matchers) {
+ return cast(Run.class, allOf(matchers));
+ }
+
+ private static <T, U> Matcher<U> cast(Class<T> clazz, Matcher<? super T> downcastMatcher) {
+ return new TypeSafeDiagnosingMatcher<U>() {
+ @Override
+ public void describeTo(Description description) {
+ downcastMatcher.describeTo(description);
+ }
+
+ @Override
+ protected boolean matchesSafely(Object item, Description mismatchDescription) {
+ if (!clazz.isInstance(item)) {
+ mismatchDescription.appendText("was a " + item.getClass().getSimpleName());
+ return false;
+ } if (downcastMatcher.matches(item)) {
+ return true;
+ } else {
+ downcastMatcher.describeMismatch(item, mismatchDescription);
+ return false;
+ }
+ }
+ };
+ }
+
+ @SafeVarargs
+ static Matcher<DocumentElement> isHyperlink(Matcher<? super Hyperlink>... matchers) {
+ return cast(Hyperlink.class, allOf(matchers));
+ }
+
+ static Matcher<Hyperlink> hasHref(String href) {
+ return hasProperty("href", equalTo(Optional.of(href)));
+ }
+}