You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

LayoutEngineTester.java 9.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. /* $Id$ */
  18. package org.apache.fop.layoutengine;
  19. import java.io.File;
  20. import java.io.IOException;
  21. import java.util.Collection;
  22. import java.util.List;
  23. import javax.xml.parsers.ParserConfigurationException;
  24. import javax.xml.transform.Source;
  25. import javax.xml.transform.Transformer;
  26. import javax.xml.transform.TransformerException;
  27. import javax.xml.transform.TransformerFactory;
  28. import javax.xml.transform.dom.DOMResult;
  29. import javax.xml.transform.dom.DOMSource;
  30. import javax.xml.transform.sax.SAXResult;
  31. import javax.xml.transform.sax.TransformerHandler;
  32. import org.apache.fop.DebugHelper;
  33. import org.apache.fop.apps.FOUserAgent;
  34. import org.apache.fop.apps.Fop;
  35. import org.apache.fop.apps.FopFactory;
  36. import org.apache.fop.apps.FormattingResults;
  37. import org.apache.fop.area.AreaTreeModel;
  38. import org.apache.fop.area.AreaTreeParser;
  39. import org.apache.fop.area.RenderPagesModel;
  40. import org.apache.fop.events.model.EventSeverity;
  41. import org.apache.fop.fonts.FontInfo;
  42. import org.apache.fop.intermediate.IFTester;
  43. import org.apache.fop.intermediate.TestAssistant;
  44. import org.apache.fop.layoutmgr.ElementListObserver;
  45. import org.apache.fop.render.intermediate.IFContext;
  46. import org.apache.fop.render.intermediate.IFRenderer;
  47. import org.apache.fop.render.intermediate.IFSerializer;
  48. import org.apache.fop.render.xml.XMLRenderer;
  49. import org.apache.fop.util.ConsoleEventListenerForTests;
  50. import org.apache.fop.util.DelegatingContentHandler;
  51. import org.junit.BeforeClass;
  52. import org.junit.Test;
  53. import org.junit.runner.RunWith;
  54. import org.junit.runners.Parameterized;
  55. import org.junit.runners.Parameterized.Parameters;
  56. import org.w3c.dom.Document;
  57. import org.w3c.dom.Element;
  58. import org.w3c.dom.NodeList;
  59. import org.xml.sax.ContentHandler;
  60. import org.xml.sax.SAXException;
  61. /**
  62. * Class for testing the FOP's layout engine using testcases specified in XML
  63. * files.
  64. */
  65. @RunWith(Parameterized.class)
  66. public class LayoutEngineTester {
  67. private static File areaTreeBackupDir;
  68. /**
  69. * Sets up the class, this is invoked only once.
  70. */
  71. @BeforeClass
  72. public static void makeDirAndRegisterDebugHelper() {
  73. DebugHelper.registerStandardElementListObservers();
  74. areaTreeBackupDir = new File("build/test-results/layoutengine");
  75. areaTreeBackupDir.mkdirs();
  76. }
  77. /**
  78. * Creates the parameters for this test.
  79. *
  80. * @return the list of file arrays populated with test files
  81. * @throws IOException if an I/O error occurs while reading the test file
  82. */
  83. @Parameters
  84. public static Collection<File[]> getParameters() throws IOException {
  85. return LayoutEngineTestUtils.getTestFiles();
  86. }
  87. private TestAssistant testAssistant = new TestAssistant();
  88. private LayoutEngineChecksFactory layoutEngineChecksFactory = new LayoutEngineChecksFactory();
  89. private IFTester ifTester;
  90. private File testFile;
  91. private TransformerFactory tfactory = TransformerFactory.newInstance();
  92. /**
  93. * Constructs a new instance.
  94. *
  95. * @param testFile the test file
  96. */
  97. public LayoutEngineTester(File testFile) {
  98. this.ifTester = new IFTester(tfactory, areaTreeBackupDir);
  99. this.testFile = testFile;
  100. }
  101. /**
  102. * Runs a single layout engine test case.
  103. * @throws TransformerException In case of an XSLT/JAXP problem
  104. * @throws IOException In case of an I/O problem
  105. * @throws SAXException In case of a problem during SAX processing
  106. * @throws ParserConfigurationException In case of a problem with the XML parser setup
  107. */
  108. @Test
  109. public void runTest() throws TransformerException, SAXException, IOException,
  110. ParserConfigurationException {
  111. DOMResult domres = new DOMResult();
  112. ElementListCollector elCollector = new ElementListCollector();
  113. ElementListObserver.addObserver(elCollector);
  114. Fop fop;
  115. FopFactory effFactory;
  116. try {
  117. Document testDoc = testAssistant.loadTestCase(testFile);
  118. effFactory = testAssistant.getFopFactory(testDoc);
  119. //Setup Transformer to convert the testcase XML to XSL-FO
  120. Transformer transformer = testAssistant.getTestcase2FOStylesheet().newTransformer();
  121. Source src = new DOMSource(testDoc);
  122. //Setup Transformer to convert the area tree to a DOM
  123. TransformerHandler athandler;
  124. athandler = testAssistant.getTransformerFactory().newTransformerHandler();
  125. athandler.setResult(domres);
  126. //Setup FOP for area tree rendering
  127. FOUserAgent ua = effFactory.newFOUserAgent();
  128. ua.setBaseURL(testFile.getParentFile().toURI().toURL().toString());
  129. ua.getEventBroadcaster().addEventListener(
  130. new ConsoleEventListenerForTests(testFile.getName(), EventSeverity.WARN));
  131. XMLRenderer atrenderer = new XMLRenderer();
  132. atrenderer.setUserAgent(ua);
  133. atrenderer.setContentHandler(athandler);
  134. ua.setRendererOverride(atrenderer);
  135. fop = effFactory.newFop(ua);
  136. SAXResult fores = new SAXResult(fop.getDefaultHandler());
  137. transformer.transform(src, fores);
  138. } finally {
  139. ElementListObserver.removeObserver(elCollector);
  140. }
  141. Document doc = (Document)domres.getNode();
  142. if (this.areaTreeBackupDir != null) {
  143. testAssistant.saveDOM(doc,
  144. new File(this.areaTreeBackupDir, testFile.getName() + ".at.xml"));
  145. }
  146. FormattingResults results = fop.getResults();
  147. LayoutResult result = new LayoutResult(doc, elCollector, results);
  148. checkAll(effFactory, testFile, result);
  149. }
  150. /**
  151. * Perform all checks on the area tree and, optionally, on the intermediate format.
  152. * @param testFile Test case XML file
  153. * @param result The layout results
  154. * @throws TransformerException if a problem occurs in XSLT/JAXP
  155. */
  156. protected void checkAll(FopFactory fopFactory, File testFile, LayoutResult result)
  157. throws TransformerException {
  158. Element testRoot = testAssistant.getTestRoot(testFile);
  159. NodeList nodes;
  160. //AT tests only when checks are available
  161. nodes = testRoot.getElementsByTagName("at-checks");
  162. if (nodes.getLength() > 0) {
  163. Element atChecks = (Element)nodes.item(0);
  164. doATChecks(atChecks, result);
  165. }
  166. //IF tests only when checks are available
  167. nodes = testRoot.getElementsByTagName("if-checks");
  168. if (nodes.getLength() > 0) {
  169. Element ifChecks = (Element)nodes.item(0);
  170. Document ifDocument = createIF(fopFactory, testFile, result.getAreaTree());
  171. ifTester.doIFChecks(testFile.getName(), ifChecks, ifDocument);
  172. }
  173. }
  174. private Document createIF(FopFactory fopFactory, File testFile, Document areaTreeXML)
  175. throws TransformerException {
  176. try {
  177. FOUserAgent ua = fopFactory.newFOUserAgent();
  178. ua.setBaseURL(testFile.getParentFile().toURI().toURL().toExternalForm());
  179. ua.getEventBroadcaster().addEventListener(
  180. new ConsoleEventListenerForTests(testFile.getName(), EventSeverity.WARN));
  181. IFRenderer ifRenderer = new IFRenderer();
  182. ifRenderer.setUserAgent(ua);
  183. IFSerializer serializer = new IFSerializer();
  184. serializer.setContext(new IFContext(ua));
  185. DOMResult result = new DOMResult();
  186. serializer.setResult(result);
  187. ifRenderer.setDocumentHandler(serializer);
  188. ua.setRendererOverride(ifRenderer);
  189. FontInfo fontInfo = new FontInfo();
  190. //Construct the AreaTreeModel that will received the individual pages
  191. final AreaTreeModel treeModel = new RenderPagesModel(ua,
  192. null, fontInfo, null);
  193. //Iterate over all intermediate files
  194. AreaTreeParser parser = new AreaTreeParser();
  195. ContentHandler handler = parser.getContentHandler(treeModel, ua);
  196. DelegatingContentHandler proxy = new DelegatingContentHandler() {
  197. public void endDocument() throws SAXException {
  198. super.endDocument();
  199. //Signal the end of the processing.
  200. //The renderer can finalize the target document.
  201. treeModel.endDocument();
  202. }
  203. };
  204. proxy.setDelegateContentHandler(handler);
  205. Transformer transformer = tfactory.newTransformer();
  206. transformer.transform(new DOMSource(areaTreeXML), new SAXResult(proxy));
  207. return (Document)result.getNode();
  208. } catch (Exception e) {
  209. throw new TransformerException(
  210. "Error while generating intermediate format file: " + e.getMessage(), e);
  211. }
  212. }
  213. private void doATChecks(Element checksRoot, LayoutResult result) {
  214. List<LayoutEngineCheck> checks = layoutEngineChecksFactory.createCheckList(checksRoot);
  215. if (checks.size() == 0) {
  216. throw new RuntimeException("No available area tree check");
  217. }
  218. for (LayoutEngineCheck check : checks) {
  219. check.check(result);
  220. }
  221. }
  222. }