aboutsummaryrefslogtreecommitdiffstats
path: root/test/java/org/apache/fop/layoutengine
diff options
context:
space:
mode:
Diffstat (limited to 'test/java/org/apache/fop/layoutengine')
-rw-r--r--test/java/org/apache/fop/layoutengine/ElementListCheck.java235
-rw-r--r--test/java/org/apache/fop/layoutengine/ElementListCollector.java89
-rw-r--r--test/java/org/apache/fop/layoutengine/EvalCheck.java10
-rw-r--r--test/java/org/apache/fop/layoutengine/LayoutEngineCheck.java6
-rw-r--r--test/java/org/apache/fop/layoutengine/LayoutEngineTestSuite.java5
-rw-r--r--test/java/org/apache/fop/layoutengine/LayoutEngineTester.java55
-rw-r--r--test/java/org/apache/fop/layoutengine/LayoutResult.java51
-rw-r--r--test/java/org/apache/fop/layoutengine/TrueCheck.java9
8 files changed, 421 insertions, 39 deletions
diff --git a/test/java/org/apache/fop/layoutengine/ElementListCheck.java b/test/java/org/apache/fop/layoutengine/ElementListCheck.java
new file mode 100644
index 000000000..4c28a0dd9
--- /dev/null
+++ b/test/java/org/apache/fop/layoutengine/ElementListCheck.java
@@ -0,0 +1,235 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.layoutengine;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.fop.layoutmgr.KnuthBox;
+import org.apache.fop.layoutmgr.KnuthElement;
+import org.apache.fop.layoutmgr.KnuthGlue;
+import org.apache.fop.layoutmgr.KnuthPenalty;
+import org.w3c.dom.CDATASection;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+/**
+ * Check implementation that checks a Knuth element list.
+ */
+public class ElementListCheck implements LayoutEngineCheck {
+
+ private String category;
+ private String id;
+ private int index = -1;
+ private Element checkElement;
+
+ /**
+ * Creates a new instance from a DOM node.
+ * @param node DOM node that defines this check
+ */
+ public ElementListCheck(Node node) {
+ this.category = node.getAttributes().getNamedItem("category").getNodeValue();
+ if (node.getAttributes().getNamedItem("id") != null) {
+ this.id = node.getAttributes().getNamedItem("id").getNodeValue();
+ }
+ if (!haveID()) {
+ if (node.getAttributes().getNamedItem("index") != null) {
+ String s = node.getAttributes().getNamedItem("index").getNodeValue();
+ this.index = Integer.parseInt(s);
+ }
+ }
+ this.checkElement = (Element)node;
+ }
+
+ /**
+ * @see org.apache.fop.layoutengine.LayoutEngineCheck
+ */
+ public void check(LayoutResult result) {
+ ElementListCollector.ElementList elementList = findElementList(result);
+ NodeList children = checkElement.getChildNodes();
+ int pos = -1;
+ for (int i = 0; i < children.getLength(); i++) {
+ Node node = children.item(i);
+ if (node instanceof Element) {
+ pos++;
+ Element domEl = (Element)node;
+ KnuthElement knuthEl = (KnuthElement)elementList.getElementList().get(pos);
+ if ("skip".equals(domEl.getLocalName())) {
+ pos += Integer.parseInt(getElementText(domEl)) - 1;
+ } else if ("box".equals(domEl.getLocalName())) {
+ if (!(knuthEl instanceof KnuthBox)) {
+ fail("Expected KnuthBox"
+ + " at position " + pos
+ + " but got: " + knuthEl.getClass().getName());
+ }
+ if (domEl.getAttribute("w").length() > 0) {
+ int w = Integer.parseInt(domEl.getAttribute("w"));
+ if (w != knuthEl.getW()) {
+ fail("Expected w=" + w
+ + " at position " + pos
+ + " but got: " + knuthEl.getW());
+ }
+ }
+ } else if ("penalty".equals(domEl.getLocalName())) {
+ if (!(knuthEl instanceof KnuthPenalty)) {
+ fail("Expected KnuthPenalty "
+ + " at position " + pos
+ + " but got: " + knuthEl.getClass().getName());
+ }
+ KnuthPenalty pen = (KnuthPenalty)knuthEl;
+ if (domEl.getAttribute("w").length() > 0) {
+ int w = Integer.parseInt(domEl.getAttribute("w"));
+ if (w != knuthEl.getW()) {
+ fail("Expected w=" + w
+ + " at position " + pos
+ + " but got: " + knuthEl.getW());
+ }
+ }
+ if (domEl.getAttribute("p").length() > 0) {
+ int p;
+ if ("INF".equalsIgnoreCase(domEl.getAttribute("p"))) {
+ p = KnuthPenalty.INFINITE;
+ } else if ("INFINITE".equalsIgnoreCase(domEl.getAttribute("p"))) {
+ p = KnuthPenalty.INFINITE;
+ } else if ("-INF".equalsIgnoreCase(domEl.getAttribute("p"))) {
+ p = -KnuthPenalty.INFINITE;
+ } else if ("-INFINITE".equalsIgnoreCase(domEl.getAttribute("p"))) {
+ p = -KnuthPenalty.INFINITE;
+ } else {
+ p = Integer.parseInt(domEl.getAttribute("p"));
+ }
+ if (p != knuthEl.getP()) {
+ fail("Expected p=" + p
+ + " at position " + pos
+ + " but got: " + knuthEl.getP());
+ }
+ }
+ if ("true".equals(domEl.getAttribute("flagged"))) {
+ if (!pen.isFlagged()) {
+ fail("Expected flagged penalty"
+ + " at position " + pos);
+ }
+ } else if ("false".equals(domEl.getAttribute("flagged"))) {
+ if (pen.isFlagged()) {
+ fail("Expected non-flagged penalty"
+ + " at position " + pos);
+ }
+ }
+ if ("true".equals(domEl.getAttribute("aux"))) {
+ if (!pen.isAuxiliary()) {
+ fail("Expected auxiliary penalty"
+ + " at position " + pos);
+ }
+ } else if ("false".equals(domEl.getAttribute("aux"))) {
+ if (pen.isAuxiliary()) {
+ fail("Expected non-auxiliary penalty"
+ + " at position " + pos);
+ }
+ }
+ } else if ("glue".equals(domEl.getLocalName())) {
+ if (!(knuthEl instanceof KnuthGlue)) {
+ fail("Expected KnuthGlue"
+ + " at position " + pos
+ + " but got: " + knuthEl.getClass().getName());
+ }
+ KnuthGlue glue = (KnuthGlue)knuthEl;
+ if (domEl.getAttribute("w").length() > 0) {
+ int w = Integer.parseInt(domEl.getAttribute("w"));
+ if (w != knuthEl.getW()) {
+ fail("Expected w=" + w
+ + " at position " + pos
+ + " but got: " + knuthEl.getW());
+ }
+ }
+ //TODO Check stretch and shrink
+ } else {
+ throw new IllegalArgumentException("Invalid child node for 'element-list': "
+ + domEl.getLocalName()
+ + " at position " + pos + " (" + this + ")");
+ }
+
+ }
+ }
+ pos++;
+ if (elementList.getElementList().size() > pos) {
+ fail("There are "
+ + (elementList.getElementList().size() - pos)
+ + " unchecked elements at the end of the list");
+ }
+ }
+
+ private void fail(String msg) {
+ throw new RuntimeException(msg + " (" + this + ")");
+ }
+
+ private boolean haveID() {
+ return (this.id != null && this.id.length() > 0);
+ }
+
+ private ElementListCollector.ElementList findElementList(LayoutResult result) {
+ List candidates = new java.util.ArrayList();
+ Iterator iter = result.getElementListCollector().getElementLists().iterator();
+ while (iter.hasNext()) {
+ ElementListCollector.ElementList el = (ElementListCollector.ElementList)iter.next();
+ if (el.getCategory().equals(category)) {
+ if (haveID() && this.id.equals(el.getID())) {
+ candidates.add(el);
+ break;
+ } else if (!haveID()) {
+ candidates.add(el);
+ }
+ }
+ }
+ if (candidates.size() == 0) {
+ throw new ArrayIndexOutOfBoundsException("Requested element list not found");
+ } else if (index >= 0) {
+ return (ElementListCollector.ElementList)candidates.get(index);
+ } else {
+ return (ElementListCollector.ElementList)candidates.get(0);
+ }
+ }
+
+ private static String getElementText(Element el) {
+ StringBuffer sb = new StringBuffer();
+ NodeList children = el.getChildNodes();
+ for (int i = 0; i < children.getLength(); i++) {
+ Node node = children.item(i);
+ if (node instanceof Text) {
+ sb.append(((Text)node).getData());
+ } else if (node instanceof CDATASection) {
+ sb.append(((CDATASection)node).getData());
+ }
+ }
+ return sb.toString();
+ }
+
+ /** @see java.lang.Object#toString() */
+ public String toString() {
+ StringBuffer sb = new StringBuffer("element-list");
+ sb.append(" category=").append(category);
+ if (haveID()) {
+ sb.append(" id=").append(id);
+ } else if (index >= 0) {
+ sb.append(" index=").append(index);
+ }
+ return sb.toString();
+ }
+}
diff --git a/test/java/org/apache/fop/layoutengine/ElementListCollector.java b/test/java/org/apache/fop/layoutengine/ElementListCollector.java
new file mode 100644
index 000000000..3956434f3
--- /dev/null
+++ b/test/java/org/apache/fop/layoutengine/ElementListCollector.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.layoutengine;
+
+import java.util.List;
+
+import org.apache.fop.layoutmgr.ElementListObserver.Observer;
+
+/**
+ * This class collects element list generated during a FOP processing run. These lists are later
+ * used to perform automated checks.
+ */
+public class ElementListCollector implements Observer {
+
+ private List elementLists = new java.util.ArrayList();
+
+ /**
+ * Resets the collector.
+ */
+ public void reset() {
+ elementLists.clear();
+ }
+
+ /**
+ * @return the list of ElementList instances.
+ */
+ public List getElementLists() {
+ return this.elementLists;
+ }
+
+ /** @see org.apache.fop.layoutmgr.ElementListObserver.Observer */
+ public void observe(List elementList, String category, String id) {
+ elementLists.add(new ElementList(elementList, category, id));
+ }
+
+ /**
+ * Data object representing an element list along with additional information.
+ */
+ public static class ElementList {
+
+ private List elementList;
+ private String category;
+ private String id;
+
+ /**
+ * Creates a new ElementList instance
+ * @param elementList the element list
+ * @param category the category for the element list
+ * @param id an optional ID
+ */
+ public ElementList(List elementList, String category, String id) {
+ this.elementList = elementList;
+ this.category = category;
+ this.id = id;
+ }
+
+ /** @return the element list */
+ public List getElementList() {
+ return elementList;
+ }
+
+ /** @return the category */
+ public String getCategory() {
+ return category;
+ }
+
+ /** @return the ID, may be null */
+ public String getID() {
+ return id;
+ }
+ }
+
+} \ No newline at end of file
diff --git a/test/java/org/apache/fop/layoutengine/EvalCheck.java b/test/java/org/apache/fop/layoutengine/EvalCheck.java
index ec15fd8f1..be71e50fb 100644
--- a/test/java/org/apache/fop/layoutengine/EvalCheck.java
+++ b/test/java/org/apache/fop/layoutengine/EvalCheck.java
@@ -21,9 +21,7 @@ package org.apache.fop.layoutengine;
import javax.xml.transform.TransformerException;
import org.apache.xpath.XPathAPI;
-import org.apache.xpath.objects.XBoolean;
import org.apache.xpath.objects.XObject;
-import org.w3c.dom.Document;
import org.w3c.dom.Node;
/**
@@ -53,13 +51,11 @@ public class EvalCheck implements LayoutEngineCheck {
this.xpath = node.getAttributes().getNamedItem("xpath").getNodeValue();
}
- /**
- * @see org.apache.fop.layoutengine.LayoutEngineCheck#check(org.w3c.dom.Document)
- */
- public void check(Document doc) {
+ /** @see org.apache.fop.layoutengine.LayoutEngineCheck */
+ public void check(LayoutResult result) {
XObject res;
try {
- res = XPathAPI.eval(doc, xpath);
+ res = XPathAPI.eval(result.getAreaTree(), xpath);
} catch (TransformerException e) {
throw new RuntimeException("XPath evaluation failed: " + e.getMessage());
}
diff --git a/test/java/org/apache/fop/layoutengine/LayoutEngineCheck.java b/test/java/org/apache/fop/layoutengine/LayoutEngineCheck.java
index c04da6537..f912e2001 100644
--- a/test/java/org/apache/fop/layoutengine/LayoutEngineCheck.java
+++ b/test/java/org/apache/fop/layoutengine/LayoutEngineCheck.java
@@ -15,8 +15,6 @@
*/
package org.apache.fop.layoutengine;
-import org.w3c.dom.Document;
-
/**
* Defines the interface for check operations.
*/
@@ -24,8 +22,8 @@ public interface LayoutEngineCheck {
/**
* Called to perform the check.
- * @param doc Area Tree DOM to check
+ * @param result the results from the processing run
*/
- void check(Document doc);
+ void check(LayoutResult result);
}
diff --git a/test/java/org/apache/fop/layoutengine/LayoutEngineTestSuite.java b/test/java/org/apache/fop/layoutengine/LayoutEngineTestSuite.java
index f005aeb2c..507189dbf 100644
--- a/test/java/org/apache/fop/layoutengine/LayoutEngineTestSuite.java
+++ b/test/java/org/apache/fop/layoutengine/LayoutEngineTestSuite.java
@@ -35,6 +35,7 @@ import org.apache.commons.io.filefilter.NotFileFilter;
import org.apache.commons.io.filefilter.PrefixFileFilter;
import org.apache.commons.io.filefilter.SuffixFileFilter;
import org.apache.commons.io.filefilter.TrueFileFilter;
+import org.apache.fop.DebugHelper;
import junit.framework.Test;
import junit.framework.TestCase;
@@ -45,6 +46,10 @@ import junit.framework.TestSuite;
*/
public class LayoutEngineTestSuite {
+ static {
+ DebugHelper.registerStandardElementListObservers();
+ }
+
private static String[] readLinesFromFile(File f) throws IOException {
List lines = new java.util.ArrayList();
Reader reader = new FileReader(f);
diff --git a/test/java/org/apache/fop/layoutengine/LayoutEngineTester.java b/test/java/org/apache/fop/layoutengine/LayoutEngineTester.java
index f8ac4b9e4..c5247adc0 100644
--- a/test/java/org/apache/fop/layoutengine/LayoutEngineTester.java
+++ b/test/java/org/apache/fop/layoutengine/LayoutEngineTester.java
@@ -43,6 +43,7 @@ import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.Fop;
import org.apache.fop.fo.Constants;
+import org.apache.fop.layoutmgr.ElementListObserver;
import org.apache.fop.render.xml.XMLRenderer;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -68,6 +69,7 @@ public class LayoutEngineTester {
static {
CHECK_CLASSES.put("true", TrueCheck.class);
CHECK_CLASSES.put("eval", EvalCheck.class);
+ CHECK_CLASSES.put("element-list", ElementListCheck.class);
}
/**
@@ -106,32 +108,41 @@ public class LayoutEngineTester {
*/
public void runTest(File testFile)
throws TransformerException, FOPException, MalformedURLException {
- //Setup Transformer to convert the testcase XML to XSL-FO
- Transformer transformer = getTestcase2FOStylesheet().newTransformer();
- Source src = new StreamSource(testFile);
- //Setup Transformer to convert the area tree to a DOM
- TransformerHandler athandler = tfactory.newTransformerHandler();
DOMResult domres = new DOMResult();
- athandler.setResult(domres);
-
- //Setup FOP for area tree rendering
- FOUserAgent ua = new FOUserAgent();
- ua.setBaseURL(testFile.getParentFile().toURL().toString());
- XMLRenderer atrenderer = new XMLRenderer();
- atrenderer.setUserAgent(ua);
- atrenderer.setTransformerHandler(athandler);
- ua.setRendererOverride(atrenderer);
- Fop fop = new Fop(Constants.RENDER_XML, ua);
-
- SAXResult fores = new SAXResult(fop.getDefaultHandler());
- transformer.transform(src, fores);
+
+ ElementListCollector elCollector = new ElementListCollector();
+ ElementListObserver.addObserver(elCollector);
+ try {
+ //Setup Transformer to convert the testcase XML to XSL-FO
+ Transformer transformer = getTestcase2FOStylesheet().newTransformer();
+ Source src = new StreamSource(testFile);
+
+ //Setup Transformer to convert the area tree to a DOM
+ TransformerHandler athandler = tfactory.newTransformerHandler();
+ athandler.setResult(domres);
+
+ //Setup FOP for area tree rendering
+ FOUserAgent ua = new FOUserAgent();
+ ua.setBaseURL(testFile.getParentFile().toURL().toString());
+ XMLRenderer atrenderer = new XMLRenderer();
+ atrenderer.setUserAgent(ua);
+ atrenderer.setTransformerHandler(athandler);
+ ua.setRendererOverride(atrenderer);
+ Fop fop = new Fop(Constants.RENDER_XML, ua);
+
+ SAXResult fores = new SAXResult(fop.getDefaultHandler());
+ transformer.transform(src, fores);
+ } finally {
+ ElementListObserver.removeObserver(elCollector);
+ }
Document doc = (Document)domres.getNode();
if (this.areaTreeBackupDir != null) {
saveAreaTreeXML(doc, new File(this.areaTreeBackupDir, testFile.getName() + ".at.xml"));
}
- checkAll(testFile, doc);
+ LayoutResult result = new LayoutResult(doc, elCollector);
+ checkAll(testFile, result);
}
/**
@@ -159,10 +170,10 @@ public class LayoutEngineTester {
/**
* Perform all checks on the area tree.
* @param testFile Test case XML file
- * @param at The generated area tree
+ * @param result The layout results
* @throws TransformerException if a problem occurs in XSLT/JAXP
*/
- protected void checkAll(File testFile, Document at) throws TransformerException {
+ protected void checkAll(File testFile, LayoutResult result) throws TransformerException {
Transformer transformer = getTestcase2ChecksStylesheet().newTransformer();
Source src = new StreamSource(testFile);
DOMResult res = new DOMResult();
@@ -181,7 +192,7 @@ public class LayoutEngineTester {
Iterator i = checks.iterator();
while (i.hasNext()) {
LayoutEngineCheck check = (LayoutEngineCheck)i.next();
- check.check(at);
+ check.check(result);
}
}
diff --git a/test/java/org/apache/fop/layoutengine/LayoutResult.java b/test/java/org/apache/fop/layoutengine/LayoutResult.java
new file mode 100644
index 000000000..b85ecda1b
--- /dev/null
+++ b/test/java/org/apache/fop/layoutengine/LayoutResult.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.layoutengine;
+
+import org.w3c.dom.Document;
+
+/**
+ * This class holds references to all the results from the FOP processing run.
+ */
+public class LayoutResult {
+
+ private Document areaTree;
+ private ElementListCollector elCollector;
+
+ /**
+ * Creates a new LayoutResult instance.
+ * @param areaTree the area tree DOM
+ * @param elCollector the element list collector
+ */
+ public LayoutResult(Document areaTree, ElementListCollector elCollector) {
+ this.areaTree = areaTree;
+ this.elCollector = elCollector;
+ }
+
+ /** @return the generated area tree as DOM tree */
+ public Document getAreaTree() {
+ return this.areaTree;
+ }
+
+ /** @return the element list collector */
+ public ElementListCollector getElementListCollector() {
+ return this.elCollector;
+ }
+
+}
diff --git a/test/java/org/apache/fop/layoutengine/TrueCheck.java b/test/java/org/apache/fop/layoutengine/TrueCheck.java
index 68a791503..8ecaf9b0b 100644
--- a/test/java/org/apache/fop/layoutengine/TrueCheck.java
+++ b/test/java/org/apache/fop/layoutengine/TrueCheck.java
@@ -23,7 +23,6 @@ import javax.xml.transform.TransformerException;
import org.apache.xpath.XPathAPI;
import org.apache.xpath.objects.XBoolean;
import org.apache.xpath.objects.XObject;
-import org.w3c.dom.Document;
import org.w3c.dom.Node;
/**
@@ -49,13 +48,11 @@ public class TrueCheck implements LayoutEngineCheck {
this.xpath = node.getAttributes().getNamedItem("xpath").getNodeValue();
}
- /**
- * @see org.apache.fop.layoutengine.LayoutEngineCheck#check(org.w3c.dom.Document)
- */
- public void check(Document doc) {
+ /** @see org.apache.fop.layoutengine.LayoutEngineCheck */
+ public void check(LayoutResult result) {
XObject res;
try {
- res = XPathAPI.eval(doc, xpath);
+ res = XPathAPI.eval(result.getAreaTree(), xpath);
} catch (TransformerException e) {
throw new RuntimeException("XPath evaluation failed: " + e.getMessage());
}