diff options
Diffstat (limited to 'test/java/org/apache/fop/layoutengine')
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()); } |