diff options
author | Jeremias Maerki <jeremias@apache.org> | 2005-01-05 21:11:34 +0000 |
---|---|---|
committer | Jeremias Maerki <jeremias@apache.org> | 2005-01-05 21:11:34 +0000 |
commit | 8e1c2320d571833575def45f89e3064e667e4f00 (patch) | |
tree | 1127ee42910f1c50b2f06e6ee86d4759c2272783 /test/java/org/apache/fop | |
parent | 02df8d85a616d663877d86f3858fb16b4c48e09f (diff) | |
download | xmlgraphics-fop-8e1c2320d571833575def45f89e3064e667e4f00.tar.gz xmlgraphics-fop-8e1c2320d571833575def45f89e3064e667e4f00.zip |
Initial version of a layout engine testing subsystem.
Uses the area tree XML to check the output of the layout engine.
Provides a TestSuite for use with JUnit.
Individual test cases are defined in XML files.
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@198225 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'test/java/org/apache/fop')
4 files changed, 386 insertions, 0 deletions
diff --git a/test/java/org/apache/fop/layoutengine/LayoutEngineCheck.java b/test/java/org/apache/fop/layoutengine/LayoutEngineCheck.java new file mode 100644 index 000000000..c04da6537 --- /dev/null +++ b/test/java/org/apache/fop/layoutengine/LayoutEngineCheck.java @@ -0,0 +1,31 @@ +/* + * 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. + */ +package org.apache.fop.layoutengine; + +import org.w3c.dom.Document; + +/** + * Defines the interface for check operations. + */ +public interface LayoutEngineCheck { + + /** + * Called to perform the check. + * @param doc Area Tree DOM to check + */ + void check(Document doc); + +} diff --git a/test/java/org/apache/fop/layoutengine/LayoutEngineTestSuite.java b/test/java/org/apache/fop/layoutengine/LayoutEngineTestSuite.java new file mode 100644 index 000000000..4bfffbe63 --- /dev/null +++ b/test/java/org/apache/fop/layoutengine/LayoutEngineTestSuite.java @@ -0,0 +1,88 @@ +/* + * 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.io.File; +import java.util.Collection; +import java.util.Iterator; + +import org.apache.commons.io.FileUtils; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * JUnit test suit for running layout engine test under JUnit control. + */ +public class LayoutEngineTestSuite { + + /** + * @return the test suite with all the tests (one for each XML file) + */ + public static Test suite() { + TestSuite suite = new TestSuite(); + + File mainDir = new File("test/layoutengine"); + File backupDir = new File("build/test-results/layoutengine"); + backupDir.mkdirs(); + + final LayoutEngineTester tester = new LayoutEngineTester(backupDir); + + Collection files = FileUtils.listFiles(new File(mainDir, "testcases"), + new String[] {"xml"}, true); + Iterator i = files.iterator(); + while (i.hasNext()) { + File f = (File)i.next(); + addTestCase(suite, tester, f); + } + + return suite; + } + + private static void addTestCase(TestSuite suite, + final LayoutEngineTester tester, final File f) { + suite.addTest(new LayoutEngineTestCase(f.getName()) { + public void runTest() throws Exception { + prepare(tester, f); + testMain(); + } + }); + } + + private static class LayoutEngineTestCase extends TestCase { + + private LayoutEngineTester tester; + private File testFile; + + public LayoutEngineTestCase(String name) { + super(name); + } + + public void prepare(LayoutEngineTester tester, File testFile) { + //super(testFile.getName()); + this.tester = tester; + this.testFile = testFile; + } + + public void testMain() throws Exception { + tester.runTest(testFile); + } + } +} diff --git a/test/java/org/apache/fop/layoutengine/LayoutEngineTester.java b/test/java/org/apache/fop/layoutengine/LayoutEngineTester.java new file mode 100644 index 000000000..05967d413 --- /dev/null +++ b/test/java/org/apache/fop/layoutengine/LayoutEngineTester.java @@ -0,0 +1,192 @@ +/* + * 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.io.File; +import java.lang.reflect.Constructor; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.Templates; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.dom.DOMResult; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.sax.SAXResult; +import javax.xml.transform.sax.SAXTransformerFactory; +import javax.xml.transform.sax.TransformerHandler; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; + +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.render.xml.XMLRenderer; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +/** + * Class for testing the FOP's layout engine using testcases specified in XML + * files. + */ +public class LayoutEngineTester { + + private static final Map CHECK_CLASSES = new java.util.HashMap(); + + private SAXTransformerFactory tfactory + = (SAXTransformerFactory)SAXTransformerFactory.newInstance(); + + private Templates testcase2fo; + private Templates testcase2checks; + + private File areaTreeBackupDir; + + static { + CHECK_CLASSES.put("true", TrueCheck.class); + } + + /** + * Constructs a new instance. + * @param areaTreeBackupDir Optional directory that receives the generated + * area tree XML files. May be null. + */ + public LayoutEngineTester(File areaTreeBackupDir) { + this.areaTreeBackupDir = areaTreeBackupDir; + } + + private Templates getTestcase2FOStylesheet() throws TransformerConfigurationException { + if (testcase2fo == null) { + //Load and cache stylesheet + Source src = new StreamSource(new File("test/layoutengine/testcase2fo.xsl")); + testcase2fo = tfactory.newTemplates(src); + } + return testcase2fo; + } + + private Templates getTestcase2ChecksStylesheet() throws TransformerConfigurationException { + if (testcase2checks == null) { + //Load and cache stylesheet + Source src = new StreamSource(new File("test/layoutengine/testcase2checks.xsl")); + testcase2checks = tfactory.newTemplates(src); + } + return testcase2checks; + } + + /** + * Runs a single layout engine test case. + * @param testFile Test case to run + * @throws TransformerException In case of an XSLT/JAXP problem + * @throws FOPException In case of a FOP problem + */ + public void runTest(File testFile) throws TransformerException, FOPException { + //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(); + 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); + + Document doc = (Document)domres.getNode(); + if (this.areaTreeBackupDir != null) { + saveAreaTreeXML(doc, new File(this.areaTreeBackupDir, testFile.getName() + ".at.xml")); + } + checkAll(testFile, doc); + } + + /** + * Factory method to create checks from DOM nodes. + * @param node DOM node to create the check from + * @return The newly create check + */ + protected LayoutEngineCheck createCheck(Node node) { + String name = node.getLocalName(); + Class clazz = (Class)CHECK_CLASSES.get(name); + if (clazz != null) { + try { + Constructor c = clazz.getDeclaredConstructor(new Class[] {Node.class}); + LayoutEngineCheck instance = (LayoutEngineCheck)c.newInstance(new Object[] {node}); + return instance; + } catch (Exception e) { + throw new RuntimeException("Error while instantiating check '" + + name + "': " + e.getMessage()); + } + } else { + throw new IllegalArgumentException("No check class found: " + name); + } + } + + /** + * Perform all checks on the area tree. + * @param testFile Test case XML file + * @param at The generated area tree + * @throws TransformerException if a problem occurs in XSLT/JAXP + */ + protected void checkAll(File testFile, Document at) throws TransformerException { + Transformer transformer = getTestcase2ChecksStylesheet().newTransformer(); + Source src = new StreamSource(testFile); + DOMResult res = new DOMResult(); + transformer.transform(src, res); + + List checks = new java.util.ArrayList(); + Document doc = (Document)res.getNode(); + NodeList nodes = doc.getDocumentElement().getChildNodes(); + for (int i = 0; i < nodes.getLength(); i++) { + Node node = nodes.item(i); + checks.add(createCheck(node)); + } + + Iterator i = checks.iterator(); + while (i.hasNext()) { + LayoutEngineCheck check = (LayoutEngineCheck)i.next(); + check.check(at); + } + } + + /** + * Save the area tree XML for later inspection. + * @param doc area tree as a DOM document + * @param target target file + * @throws TransformerException if a problem occurs during serialization + */ + protected void saveAreaTreeXML(Document doc, File target) throws TransformerException { + Transformer transformer = tfactory.newTransformer(); + Source src = new DOMSource(doc); + Result res = new StreamResult(target); + transformer.transform(src, res); + } +} diff --git a/test/java/org/apache/fop/layoutengine/TrueCheck.java b/test/java/org/apache/fop/layoutengine/TrueCheck.java new file mode 100644 index 000000000..68a791503 --- /dev/null +++ b/test/java/org/apache/fop/layoutengine/TrueCheck.java @@ -0,0 +1,75 @@ +/* + * 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 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; + +/** + * Simple check that requires an XPath expression to evaluate to true. + */ +public class TrueCheck implements LayoutEngineCheck { + + private String xpath; + + /** + * Creates a new instance + * @param xpath XPath statement that needs to be evaluated + */ + public TrueCheck(String xpath) { + this.xpath = xpath; + } + + /** + * Creates a new instance from a DOM node. + * @param node DOM node that defines this check + */ + public TrueCheck(Node node) { + this.xpath = node.getAttributes().getNamedItem("xpath").getNodeValue(); + } + + /** + * @see org.apache.fop.layoutengine.LayoutEngineCheck#check(org.w3c.dom.Document) + */ + public void check(Document doc) { + XObject res; + try { + res = XPathAPI.eval(doc, xpath); + } catch (TransformerException e) { + throw new RuntimeException("XPath evaluation failed: " + e.getMessage()); + } + if (!XBoolean.S_TRUE.equals(res)) { + throw new RuntimeException( + "Expected XPath expression to evaluate to 'true', but got '" + + res + "' (" + this + ")"); + } + + } + + /** @see java.lang.Object#toString() */ + public String toString() { + return "XPath: " + xpath; + } + +} |