diff options
author | Vincent Hennebert <vhennebert@apache.org> | 2011-10-24 16:29:56 +0000 |
---|---|---|
committer | Vincent Hennebert <vhennebert@apache.org> | 2011-10-24 16:29:56 +0000 |
commit | b073a605e44760bcb7add72968a3a2f78cf06d97 (patch) | |
tree | 50501d5167416c5a5a31f2319102efee829a8bd8 /test | |
parent | 29ecb2d96c4c4b75785e160a55c7dc436cfef860 (diff) | |
download | xmlgraphics-fop-b073a605e44760bcb7add72968a3a2f78cf06d97.tar.gz xmlgraphics-fop-b073a605e44760bcb7add72968a3a2f78cf06d97.zip |
Removed the FO document pre-processing step that was adding ptr and creating a reduced FO tree.
* Removed addPtr.xsl and reduceFOTree.xsl
* Implemented Common Accessibility properties on objects that support them
* Added a special implementation of FOEventHandler to build the structure tree
* Added mockito library and its dependencies
* Added mocks for some FO nodes and properties
* Removed FOTreeUnitTester and converted it into a re-usable FODocumentParser class
* Re-worked table FO test cases accordingly
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_ImproveAccessibility@1188205 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'test')
57 files changed, 1484 insertions, 161 deletions
diff --git a/test/accessibility/README b/test/accessibility/README index 391d39055..1d2e04361 100644 --- a/test/accessibility/README +++ b/test/accessibility/README @@ -1,11 +1,8 @@ This directory contains sample FO files for testing the accessibility features of FOP. -To every FO file in this directory correspond two PDF files in the pdf/ -sub-directory: one generated by the painter, one by the renderer. For example, -the text_1.fo file has been rendered into pdf/text_1_painter_orig.pdf and -pdf/text_1_renderer_orig.pdf. The configuration file config-painter.xconf (resp. -config-renderer.xconf) was used. +Every FO file in this directory has a corresponding PDF file in the pdf/ +sub-directory. The fop.xconf configuration file was used. The PDF files have been checked with Adobe Acrobat Professional 9, using both the full accessibility checker and the read-aloud feature. The checker reports @@ -22,7 +19,7 @@ problem yet part or all of the document cannot be read aloud.) The purpose of this infrastructure is to be able to quickly re-test the accessibility processing chain when any change has been made to it. The -configuration files disable the compression of the PDF streams, so it is +configuration file disables the compression of the PDF streams, so it is possible to compare a re-generated PDF with the original one by using a simple diff tool. The files will not be identical because of the different creation dates (and the ID key in the trailer), but apart from that there should be no @@ -32,21 +29,13 @@ The rationale is that using a diff tool is much quicker and less tedious than running Acrobat's accessibility checker and read-aloud feature every time. -To re-generate the PDF files using the painter: - ../../fop -c config-painter.xconf text_1.fo pdf/text_1_painter.pdf - diff pdf/text_1_painter_orig.pdf pdf/text_1_painter.pdf +To re-generate the PDF files: + ../../fop -c fop.xconf text_1.fo pdf/text_1.new.pdf + diff pdf/text_1_painter.pdf pdf/text_1.new.pdf Or, going through the intermediate format: - ../../fop -c config-painter.xconf text_1.fo -if application/pdf text_1_if.xml - ../../fop -c config-painter.xconf -ifin text_1_if.xml pdf/text_1_painter.pdf - diff pdf/text_1_painter_orig.pdf pdf/text_1_painter.pdf - -To re-generate the PDF files using the legacy renderer: - ../../fop -c config-renderer.xconf text_1.fo pdf/text_1_renderer.pdf - diff pdf/text_1_renderer_orig.pdf pdf/text_1_renderer.pdf -Or, going through the intermediate format: - ../../fop -c config-renderer.xconf text_1.fo -at application/pdf text_1_at.xml - ../../fop -c config-renderer.xconf -atin text_1_at.xml pdf/text_1_renderer.pdf - diff pdf/text_1_renderer_orig.pdf pdf/text_1_renderer.pdf + ../../fop -c fop.xconf text_1.fo -if application/pdf text_1_if.xml + ../../fop -c fop.xconf -ifin text_1_if.xml pdf/text_1.new.pdf + diff pdf/text_1.pdf pdf/text_1.new.pdf $Id$ diff --git a/test/accessibility/pdf/background-image_jpg_repeat_painter_orig.pdf b/test/accessibility/pdf/background-image_jpg_repeat.pdf Binary files differindex c7c27f9d1..c7c27f9d1 100644 --- a/test/accessibility/pdf/background-image_jpg_repeat_painter_orig.pdf +++ b/test/accessibility/pdf/background-image_jpg_repeat.pdf diff --git a/test/accessibility/pdf/background-image_jpg_repeat_renderer_orig.pdf b/test/accessibility/pdf/background-image_jpg_repeat_renderer_orig.pdf Binary files differdeleted file mode 100644 index ee5d89d40..000000000 --- a/test/accessibility/pdf/background-image_jpg_repeat_renderer_orig.pdf +++ /dev/null diff --git a/test/accessibility/pdf/background-image_jpg_single_painter_orig.pdf b/test/accessibility/pdf/background-image_jpg_single.pdf Binary files differindex 080f0b876..080f0b876 100644 --- a/test/accessibility/pdf/background-image_jpg_single_painter_orig.pdf +++ b/test/accessibility/pdf/background-image_jpg_single.pdf diff --git a/test/accessibility/pdf/background-image_jpg_single_renderer_orig.pdf b/test/accessibility/pdf/background-image_jpg_single_renderer_orig.pdf Binary files differdeleted file mode 100644 index 4d04ca427..000000000 --- a/test/accessibility/pdf/background-image_jpg_single_renderer_orig.pdf +++ /dev/null diff --git a/test/accessibility/pdf/background-image_png_repeat_painter_orig.pdf b/test/accessibility/pdf/background-image_png_repeat.pdf Binary files differindex a10e1357e..a10e1357e 100644 --- a/test/accessibility/pdf/background-image_png_repeat_painter_orig.pdf +++ b/test/accessibility/pdf/background-image_png_repeat.pdf diff --git a/test/accessibility/pdf/background-image_png_repeat_renderer_orig.pdf b/test/accessibility/pdf/background-image_png_repeat_renderer_orig.pdf Binary files differdeleted file mode 100644 index 982c50cc9..000000000 --- a/test/accessibility/pdf/background-image_png_repeat_renderer_orig.pdf +++ /dev/null diff --git a/test/accessibility/pdf/background-image_png_single_painter_orig.pdf b/test/accessibility/pdf/background-image_png_single.pdf Binary files differindex 1e9ff00b4..1e9ff00b4 100644 --- a/test/accessibility/pdf/background-image_png_single_painter_orig.pdf +++ b/test/accessibility/pdf/background-image_png_single.pdf diff --git a/test/accessibility/pdf/background-image_png_single_renderer_orig.pdf b/test/accessibility/pdf/background-image_png_single_renderer_orig.pdf Binary files differdeleted file mode 100644 index 2c7084dd8..000000000 --- a/test/accessibility/pdf/background-image_png_single_renderer_orig.pdf +++ /dev/null diff --git a/test/accessibility/pdf/background-image_svg_repeat_painter_orig.pdf b/test/accessibility/pdf/background-image_svg_repeat.pdf Binary files differindex c641fbbe5..c641fbbe5 100644 --- a/test/accessibility/pdf/background-image_svg_repeat_painter_orig.pdf +++ b/test/accessibility/pdf/background-image_svg_repeat.pdf diff --git a/test/accessibility/pdf/background-image_svg_repeat_renderer_orig.pdf b/test/accessibility/pdf/background-image_svg_repeat_renderer_orig.pdf Binary files differdeleted file mode 100644 index 65d71109e..000000000 --- a/test/accessibility/pdf/background-image_svg_repeat_renderer_orig.pdf +++ /dev/null diff --git a/test/accessibility/pdf/background-image_svg_single_painter_orig.pdf b/test/accessibility/pdf/background-image_svg_single.pdf Binary files differindex 09a9ad895..09a9ad895 100644 --- a/test/accessibility/pdf/background-image_svg_single_painter_orig.pdf +++ b/test/accessibility/pdf/background-image_svg_single.pdf diff --git a/test/accessibility/pdf/background-image_svg_single_renderer_orig.pdf b/test/accessibility/pdf/background-image_svg_single_renderer_orig.pdf Binary files differdeleted file mode 100644 index b7c5a71e9..000000000 --- a/test/accessibility/pdf/background-image_svg_single_renderer_orig.pdf +++ /dev/null diff --git a/test/accessibility/pdf/complete_painter_orig.pdf b/test/accessibility/pdf/complete.pdf Binary files differindex caf7a41f8..caf7a41f8 100644 --- a/test/accessibility/pdf/complete_painter_orig.pdf +++ b/test/accessibility/pdf/complete.pdf diff --git a/test/accessibility/pdf/complete_renderer_orig.pdf b/test/accessibility/pdf/complete_renderer_orig.pdf Binary files differdeleted file mode 100644 index e7e4ed6c1..000000000 --- a/test/accessibility/pdf/complete_renderer_orig.pdf +++ /dev/null diff --git a/test/accessibility/pdf/image_jpg_painter_orig.pdf b/test/accessibility/pdf/image_jpg.pdf Binary files differindex 1336f99eb..1336f99eb 100644 --- a/test/accessibility/pdf/image_jpg_painter_orig.pdf +++ b/test/accessibility/pdf/image_jpg.pdf diff --git a/test/accessibility/pdf/image_jpg_renderer_orig.pdf b/test/accessibility/pdf/image_jpg_renderer_orig.pdf Binary files differdeleted file mode 100644 index 62be9c16c..000000000 --- a/test/accessibility/pdf/image_jpg_renderer_orig.pdf +++ /dev/null diff --git a/test/accessibility/pdf/image_png_painter_orig.pdf b/test/accessibility/pdf/image_png.pdf Binary files differindex b22c157b0..b22c157b0 100644 --- a/test/accessibility/pdf/image_png_painter_orig.pdf +++ b/test/accessibility/pdf/image_png.pdf diff --git a/test/accessibility/pdf/image_png_renderer_orig.pdf b/test/accessibility/pdf/image_png_renderer_orig.pdf Binary files differdeleted file mode 100644 index efd5d2bdd..000000000 --- a/test/accessibility/pdf/image_png_renderer_orig.pdf +++ /dev/null diff --git a/test/accessibility/pdf/image_svg_painter_orig.pdf b/test/accessibility/pdf/image_svg.pdf Binary files differindex 1f5393c43..1f5393c43 100644 --- a/test/accessibility/pdf/image_svg_painter_orig.pdf +++ b/test/accessibility/pdf/image_svg.pdf diff --git a/test/accessibility/pdf/image_svg_renderer_orig.pdf b/test/accessibility/pdf/image_svg_renderer_orig.pdf Binary files differdeleted file mode 100644 index 9c020706d..000000000 --- a/test/accessibility/pdf/image_svg_renderer_orig.pdf +++ /dev/null diff --git a/test/accessibility/pdf/image_wmf_painter_orig.pdf b/test/accessibility/pdf/image_wmf.pdf Binary files differindex 599b4c5ff..599b4c5ff 100644 --- a/test/accessibility/pdf/image_wmf_painter_orig.pdf +++ b/test/accessibility/pdf/image_wmf.pdf diff --git a/test/accessibility/pdf/image_wmf_renderer_orig.pdf b/test/accessibility/pdf/image_wmf_renderer_orig.pdf Binary files differdeleted file mode 100644 index c82134915..000000000 --- a/test/accessibility/pdf/image_wmf_renderer_orig.pdf +++ /dev/null diff --git a/test/accessibility/pdf/leader_painter_orig.pdf b/test/accessibility/pdf/leader.pdf Binary files differindex cf77a5c96..cf77a5c96 100644 --- a/test/accessibility/pdf/leader_painter_orig.pdf +++ b/test/accessibility/pdf/leader.pdf diff --git a/test/accessibility/pdf/leader_renderer_orig.pdf b/test/accessibility/pdf/leader_renderer_orig.pdf Binary files differdeleted file mode 100644 index 27c3afbde..000000000 --- a/test/accessibility/pdf/leader_renderer_orig.pdf +++ /dev/null diff --git a/test/accessibility/pdf/links_painter_orig.pdf b/test/accessibility/pdf/links.pdf Binary files differindex ee37c72d6..ee37c72d6 100644 --- a/test/accessibility/pdf/links_painter_orig.pdf +++ b/test/accessibility/pdf/links.pdf diff --git a/test/accessibility/pdf/links_renderer_orig.pdf b/test/accessibility/pdf/links_renderer_orig.pdf Binary files differdeleted file mode 100644 index 2bae65033..000000000 --- a/test/accessibility/pdf/links_renderer_orig.pdf +++ /dev/null diff --git a/test/accessibility/pdf/role_painter_orig.pdf b/test/accessibility/pdf/role.pdf Binary files differindex 1eaaf1a9d..1eaaf1a9d 100644 --- a/test/accessibility/pdf/role_painter_orig.pdf +++ b/test/accessibility/pdf/role.pdf diff --git a/test/accessibility/pdf/role_non-standard_painter_orig.pdf b/test/accessibility/pdf/role_non-standard.pdf Binary files differindex f8b1c9d2c..f8b1c9d2c 100644 --- a/test/accessibility/pdf/role_non-standard_painter_orig.pdf +++ b/test/accessibility/pdf/role_non-standard.pdf diff --git a/test/accessibility/pdf/role_non-standard_renderer_orig.pdf b/test/accessibility/pdf/role_non-standard_renderer_orig.pdf Binary files differdeleted file mode 100644 index 1700d7c03..000000000 --- a/test/accessibility/pdf/role_non-standard_renderer_orig.pdf +++ /dev/null diff --git a/test/accessibility/pdf/role_renderer_orig.pdf b/test/accessibility/pdf/role_renderer_orig.pdf Binary files differdeleted file mode 100644 index fc8e002a8..000000000 --- a/test/accessibility/pdf/role_renderer_orig.pdf +++ /dev/null diff --git a/test/accessibility/pdf/text_1_painter_orig.pdf b/test/accessibility/pdf/text_1.pdf Binary files differindex 2ad8a12f2..2ad8a12f2 100644 --- a/test/accessibility/pdf/text_1_painter_orig.pdf +++ b/test/accessibility/pdf/text_1.pdf diff --git a/test/accessibility/pdf/text_1_renderer_orig.pdf b/test/accessibility/pdf/text_1_renderer_orig.pdf Binary files differdeleted file mode 100644 index 67d39890c..000000000 --- a/test/accessibility/pdf/text_1_renderer_orig.pdf +++ /dev/null diff --git a/test/accessibility/pdf/text_2_painter_orig.pdf b/test/accessibility/pdf/text_2.pdf Binary files differindex 21ad6d0d8..21ad6d0d8 100644 --- a/test/accessibility/pdf/text_2_painter_orig.pdf +++ b/test/accessibility/pdf/text_2.pdf diff --git a/test/accessibility/pdf/text_2_renderer_orig.pdf b/test/accessibility/pdf/text_2_renderer_orig.pdf Binary files differdeleted file mode 100644 index 6a5956c66..000000000 --- a/test/accessibility/pdf/text_2_renderer_orig.pdf +++ /dev/null diff --git a/test/accessibility/pdf/text_font-embedding_painter_orig.pdf b/test/accessibility/pdf/text_font-embedding.pdf Binary files differindex d5c61c040..d5c61c040 100644 --- a/test/accessibility/pdf/text_font-embedding_painter_orig.pdf +++ b/test/accessibility/pdf/text_font-embedding.pdf diff --git a/test/accessibility/pdf/text_font-embedding_renderer_orig.pdf b/test/accessibility/pdf/text_font-embedding_renderer_orig.pdf Binary files differdeleted file mode 100644 index f8669cb98..000000000 --- a/test/accessibility/pdf/text_font-embedding_renderer_orig.pdf +++ /dev/null diff --git a/test/java/org/apache/fop/fo/DelegatingFOEventHandlerTestCase.fo b/test/java/org/apache/fop/fo/DelegatingFOEventHandlerTestCase.fo new file mode 100644 index 000000000..74afd6c16 --- /dev/null +++ b/test/java/org/apache/fop/fo/DelegatingFOEventHandlerTestCase.fo @@ -0,0 +1,175 @@ +<?xml version="1.0" standalone="no"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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$ --> +<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" + xmlns:fox="http://xmlgraphics.apache.org/fop/extensions"> + + <fo:layout-master-set> + <fo:simple-page-master master-name="page" + page-height="400pt" page-width="300pt" margin="20pt" margin-top="10pt"> + <fo:region-body margin-top="20pt"/> + <fo:region-before extent="15pt"/> + </fo:simple-page-master> + </fo:layout-master-set> + + <fo:page-sequence master-reference="page"> + <fo:static-content flow-name="xsl-region-before"> + <fo:block id="1" font-size="7pt" text-align-last="justify" padding-bottom="2pt" + border-bottom="0.25pt solid black">This is the page header<fo:leader/>Page <fo:page-number + id="2"/></fo:block> + </fo:static-content> + <fo:static-content flow-name="xsl-footnote-separator"> + <fo:block id="3"><fo:leader leader-length="100pt" leader-pattern="rule"/></fo:block> + </fo:static-content> + <fo:flow flow-name="xsl-region-body"> + <fo:block id="4">This is a link to the <fo:wrapper id="5" color="blue"><fo:basic-link id="6" + internal-destination="second-start">next page-sequence</fo:basic-link></fo:wrapper> + (which starts on page <fo:page-number-citation id="7" ref-id="second-start"/> and ends on + page <fo:page-number-citation-last id="8" ref-id="second-end"/>).</fo:block> + <fo:block id="9" font-family="sans-serif" font-weight="bold" space-before="1em" + space-after="0.2em" role="H1"><fo:block id="10">A Title Block</fo:block></fo:block> + <fo:block id="11">This block of text contains a footnote<fo:footnote id="12"><fo:inline id="13" + baseline-shift="super" font-size="70%">1</fo:inline><fo:footnote-body id="14"><fo:block + id="15">A footnote with a link to the <fo:wrapper id="16" color="blue"><fo:basic-link + id="17" external-destination="http://xmlgraphics.apache.org/fop/">FOP + website</fo:basic-link></fo:wrapper></fo:block></fo:footnote-body></fo:footnote> + call.</fo:block> + <fo:table id="18" space-before="1em" width="100%" table-layout="fixed"> + <fo:table-column id="19" column-width="proportional-column-width(1)"/> + <fo:table-column id="20" column-width="proportional-column-width(2)"/> + <fo:table-header id="21"> + <fo:table-row id="22"> + <fo:table-cell id="23" border="2pt solid black" padding="2pt 2pt 0"> + <fo:block id="24">Header 1.1</fo:block> + </fo:table-cell> + <fo:table-cell id="25" border="2pt solid black" padding="2pt 2pt 0"> + <fo:block id="26">Header 1.2</fo:block> + </fo:table-cell> + </fo:table-row> + </fo:table-header> + <fo:table-footer id="27"> + <fo:table-row id="28"> + <fo:table-cell id="29" border="2pt solid black" padding="2pt 2pt 0"> + <fo:block id="30">Footer 1.1</fo:block> + </fo:table-cell> + <fo:table-cell id="31" border="2pt solid black" padding="2pt 2pt 0"> + <fo:block id="32">Footer 1.2</fo:block> + </fo:table-cell> + </fo:table-row> + </fo:table-footer> + <fo:table-body id="33"> + <fo:table-row id="34"> + <fo:table-cell id="35" border="1pt solid black" padding="2pt 2pt 0"> + <fo:block id="36">Cell 1.1</fo:block> + </fo:table-cell> + <fo:table-cell id="37" border="1pt solid black" padding="2pt 2pt 0"> + <fo:block id="38">Cell 1.2</fo:block> + </fo:table-cell> + </fo:table-row> + <fo:table-row id="39"> + <fo:table-cell id="40" border="1pt solid black" padding="2pt 2pt 0"> + <fo:block id="41">Cell 2.1</fo:block> + </fo:table-cell> + <fo:table-cell id="42" border="1pt solid black" padding="2pt 2pt 0"> + <fo:block id="43">Cell 2.2</fo:block> + </fo:table-cell> + </fo:table-row> + </fo:table-body> + </fo:table> + <fo:block-container id="44" space-before="1.2em"> + <fo:block-container id="45" absolute-position="absolute" top="6pt" right="2.5pt" + inline-progression-dimension="37%" padding="3pt 1pt 2pt 3pt" border="1.5pt solid + darkblue"> + <fo:block id="46" color="darkblue" font-size="80%">This is an absolutely positioned + block-container. Nullam interdum mattis ipsum sit amet molestie.</fo:block> + </fo:block-container> + <fo:block id="47" end-indent="37% + 15pt">Lorem ipsum dolor sit amet, consectetur adipiscing + elit. Integer vel lacinia diam. Etiam venenatis magna vel libero imperdiet + rhoncus.</fo:block> + </fo:block-container> + </fo:flow> + </fo:page-sequence> + + <fo:page-sequence master-reference="page"> + <fo:static-content id="48" flow-name="xsl-region-before"> + <fo:block id="49" font-size="7pt" text-align-last="justify" padding-bottom="2pt" + border-bottom="0.25pt solid black">This is the page header<fo:leader id="50"/>Page + <fo:page-number id="51"/></fo:block> + </fo:static-content> + <fo:flow flow-name="xsl-region-body" text-align="justify" space-before.minimum="8pt" + space-before.optimum="10pt" space-before.maximum="12pt"> + <fo:block id="second-start">Starting a new page-sequence.</fo:block> + <fo:block id="52" text-align="center">The <fo:external-graphic id="53" + src="test/resources/images/fop-logo-color-24bit.png" + inline-progression-dimension.maximum="50%" content-width="scale-to-fit" + alignment-adjust="-46%" alignment-baseline="middle" fox:alt-text="FOP Logo"/> + logo.</fo:block> + <fo:list-block id="54" provisional-distance-between-starts="15pt" + provisional-label-separation="0" space-before="inherit"> + <fo:list-item id="55"> + <fo:list-item-label id="56" end-indent="label-end()"> + <fo:block id="57">1.</fo:block> + </fo:list-item-label> + <fo:list-item-body id="58" start-indent="body-start()"> + <fo:block id="59">First item of a list</fo:block> + </fo:list-item-body> + </fo:list-item> + <fo:list-item id="60"> + <fo:list-item-label id="61" end-indent="label-end()"> + <fo:block id="62">2.</fo:block> + </fo:list-item-label> + <fo:list-item-body id="63" start-indent="body-start()"> + <fo:block id="64">Second item of a list</fo:block> + </fo:list-item-body> + </fo:list-item> + <fo:list-item id="65"> + <fo:list-item-label id="66" end-indent="label-end()"> + <fo:block id="67">3.</fo:block> + </fo:list-item-label> + <fo:list-item-body id="68" start-indent="body-start()"> + <fo:block id="69">Third item of a list</fo:block> + </fo:list-item-body> + </fo:list-item> + </fo:list-block> + <fo:block id="70" text-align="center"><fo:instream-foreign-object id="71" + inline-progression-dimension.maximum="50%" content-width="scale-to-fit"> + <svg xmlns="http://www.w3.org/2000/svg" width="319" height="286.6"> + <g style="fill-opacity:0.7; stroke:black; stroke-width:3" + transform="translate(0, 286.6) scale(1, -1) translate(100, 100)"> + <circle cx="50" cy="86.6" r="80" style="fill:red;"/> + <circle cx="0" cy="0" r="80" style="fill:green;"/> + <circle cx="100" cy="0" r="80" style="fill:blue;"/> + </g> + </svg> + </fo:instream-foreign-object></fo:block> + <fo:block id="72" space-before="inherit">A block containing an <fo:inline id="73" + border="0.5pt solid black" padding="2pt" padding-bottom="0">inline</fo:inline> + element.</fo:block> + <fo:block id="74" space-before="inherit">A block containing a fancy <fo:character id="75" + border="1pt solid black" padding="0 2pt 1pt 2pt" font-family="Symbol" character="♦"/> + character.</fo:block> + <fo:block id="76" space-before="inherit" text-align-last="justify">A leader with special + content: <fo:leader id="77" leader-pattern="use-content"><fo:inline id="78"><fo:character + id="79" character=" "/><fo:inline id="80" border="0.5pt solid black" + padding-left="2pt" padding-right="2pt"><fo:character id="81" baseline-shift="-10%" + character="•"/></fo:inline></fo:inline></fo:leader>.</fo:block> + <fo:block id="second-end" space-before="inherit">Ending the page-sequence.</fo:block> + </fo:flow> + </fo:page-sequence> + +</fo:root> diff --git a/test/java/org/apache/fop/fo/DelegatingFOEventHandlerTestCase.java b/test/java/org/apache/fop/fo/DelegatingFOEventHandlerTestCase.java new file mode 100644 index 000000000..faa88e38e --- /dev/null +++ b/test/java/org/apache/fop/fo/DelegatingFOEventHandlerTestCase.java @@ -0,0 +1,522 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.fo; + +import static org.junit.Assert.assertArrayEquals; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.sax.SAXResult; +import javax.xml.transform.stream.StreamSource; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.fo.FODocumentParser.FOEventHandlerFactory; +import org.apache.fop.fo.flow.BasicLink; +import org.apache.fop.fo.flow.Block; +import org.apache.fop.fo.flow.BlockContainer; +import org.apache.fop.fo.flow.Character; +import org.apache.fop.fo.flow.ExternalGraphic; +import org.apache.fop.fo.flow.Footnote; +import org.apache.fop.fo.flow.FootnoteBody; +import org.apache.fop.fo.flow.Inline; +import org.apache.fop.fo.flow.InstreamForeignObject; +import org.apache.fop.fo.flow.Leader; +import org.apache.fop.fo.flow.ListBlock; +import org.apache.fop.fo.flow.ListItem; +import org.apache.fop.fo.flow.ListItemBody; +import org.apache.fop.fo.flow.ListItemLabel; +import org.apache.fop.fo.flow.PageNumber; +import org.apache.fop.fo.flow.PageNumberCitation; +import org.apache.fop.fo.flow.PageNumberCitationLast; +import org.apache.fop.fo.flow.Wrapper; +import org.apache.fop.fo.flow.table.Table; +import org.apache.fop.fo.flow.table.TableBody; +import org.apache.fop.fo.flow.table.TableCell; +import org.apache.fop.fo.flow.table.TableColumn; +import org.apache.fop.fo.flow.table.TableFooter; +import org.apache.fop.fo.flow.table.TableHeader; +import org.apache.fop.fo.flow.table.TableRow; +import org.apache.fop.fo.pagination.Flow; +import org.apache.fop.fo.pagination.PageSequence; +import org.apache.fop.fo.pagination.StaticContent; + +/** + * Tests that {@link DelegatingFOEventHandler} does forward every event to its delegate + * event handler. + */ +public class DelegatingFOEventHandlerTestCase { + + private InputStream document; + + private List<String> expectedEvents; + + private List<String> actualEvents; + + private FODocumentParser documentParser; + + private class DelegatingFOEventHandlerTester extends FOEventHandler { + + DelegatingFOEventHandlerTester(FOUserAgent foUserAgent) { + super(foUserAgent); + } + + private final StringBuilder eventBuilder = new StringBuilder(); + + @Override + public void startDocument() throws SAXException { + actualEvents.add("start root"); + } + + @Override + public void endDocument() throws SAXException { + actualEvents.add("end root"); + } + + @Override + public void startPageSequence(PageSequence pageSeq) { + startElement(pageSeq); + } + + @Override + public void endPageSequence(PageSequence pageSeq) { + endElement(pageSeq); + } + + @Override + public void startPageNumber(PageNumber pagenum) { + startElement(pagenum); + } + + @Override + public void endPageNumber(PageNumber pagenum) { + endElement(pagenum); + } + + @Override + public void startPageNumberCitation(PageNumberCitation pageCite) { + startElement(pageCite); + } + + @Override + public void endPageNumberCitation(PageNumberCitation pageCite) { + endElement(pageCite); + } + + @Override + public void startPageNumberCitationLast(PageNumberCitationLast pageLast) { + startElement(pageLast); + } + + @Override + public void endPageNumberCitationLast(PageNumberCitationLast pageLast) { + endElement(pageLast); + } + + @Override + public void startFlow(Flow fl) { + startElement(fl); + } + + @Override + public void endFlow(Flow fl) { + endElement(fl); + } + + @Override + public void startBlock(Block bl) { + startElement(bl); + } + + @Override + public void endBlock(Block bl) { + endElement(bl); + } + + @Override + public void startBlockContainer(BlockContainer blc) { + startElement(blc); + } + + @Override + public void endBlockContainer(BlockContainer blc) { + endElement(blc); + } + + @Override + public void startInline(Inline inl) { + startElement(inl); + } + + @Override + public void endInline(Inline inl) { + endElement(inl); + } + + @Override + public void startTable(Table tbl) { + startElement(tbl); + } + + @Override + public void endTable(Table tbl) { + endElement(tbl); + } + + @Override + public void startColumn(TableColumn tc) { + startElement(tc); + } + + @Override + public void endColumn(TableColumn tc) { + endElement(tc); + } + + @Override + public void startHeader(TableHeader header) { + startElement(header); + } + + @Override + public void endHeader(TableHeader header) { + endElement(header); + } + + @Override + public void startFooter(TableFooter footer) { + startElement(footer); + } + + @Override + public void endFooter(TableFooter footer) { + endElement(footer); + } + + @Override + public void startBody(TableBody body) { + startElement(body); + } + + @Override + public void endBody(TableBody body) { + endElement(body); + } + + @Override + public void startRow(TableRow tr) { + startElement(tr); + } + + @Override + public void endRow(TableRow tr) { + endElement(tr); + } + + @Override + public void startCell(TableCell tc) { + startElement(tc); + } + + @Override + public void endCell(TableCell tc) { + endElement(tc); + } + + @Override + public void startList(ListBlock lb) { + startElement(lb); + } + + @Override + public void endList(ListBlock lb) { + endElement(lb); + } + + @Override + public void startListItem(ListItem li) { + startElement(li); + } + + @Override + public void endListItem(ListItem li) { + endElement(li); + } + + @Override + public void startListLabel(ListItemLabel listItemLabel) { + startElement(listItemLabel); + } + + @Override + public void endListLabel(ListItemLabel listItemLabel) { + endElement(listItemLabel); + } + + @Override + public void startListBody(ListItemBody listItemBody) { + startElement(listItemBody); + } + + @Override + public void endListBody(ListItemBody listItemBody) { + endElement(listItemBody); + } + + @Override + public void startStatic(StaticContent staticContent) { + startElement(staticContent); + } + + @Override + public void endStatic(StaticContent statisContent) { + endElement(statisContent); + } + + @Override + public void startLink(BasicLink basicLink) { + startElement(basicLink); + } + + @Override + public void endLink(BasicLink basicLink) { + endElement(basicLink); + } + + @Override + public void image(ExternalGraphic eg) { + startElement(eg); + endElement(eg); + } + + @Override + public void startInstreamForeignObject(InstreamForeignObject ifo) { + startElement(ifo); + } + + @Override + public void endInstreamForeignObject(InstreamForeignObject ifo) { + endElement(ifo); + } + + @Override + public void startFootnote(Footnote footnote) { + startElement(footnote); + } + + @Override + public void endFootnote(Footnote footnote) { + endElement(footnote); + } + + @Override + public void startFootnoteBody(FootnoteBody body) { + startElement(body); + } + + @Override + public void endFootnoteBody(FootnoteBody body) { + endElement(body); + } + + @Override + public void startLeader(Leader l) { + startElement(l); + } + + @Override + public void endLeader(Leader l) { + endElement(l); + } + + @Override + public void startWrapper(Wrapper wrapper) { + startElement(wrapper); + } + + @Override + public void endWrapper(Wrapper wrapper) { + endElement(wrapper); + } + + @Override + public void character(Character c) { + startElement(c); + endElement(c); + } + + private void startElement(FObj node) { + addEvent("start ", node); + } + + private void endElement(FObj node) { + addEvent("end ", node); + } + + private void addEvent(String event, FObj node) { + eventBuilder.append(event); + eventBuilder.append(node.getLocalName()); + addID(node); + actualEvents.add(eventBuilder.toString()); + eventBuilder.setLength(0); + } + + private void addID(FObj node) { + String id = node.getId(); + if (id != null && id.length() > 0) { + eventBuilder.append(" id=\""); + eventBuilder.append(id); + eventBuilder.append("\""); + } + } + } + + @Before + public void setUp() throws IOException { + setUpEvents(); + loadDocument(); + createDocumentParser(); + } + + private void setUpEvents() throws IOException { + loadDocument(); + loadExpectedEvents(); + actualEvents = new ArrayList<String>(expectedEvents.size()); + } + + private void loadDocument() { + Class<?> clazz = getClass(); + String documentName = clazz.getSimpleName() + ".fo"; + document = clazz.getResourceAsStream(documentName); + } + + private void loadExpectedEvents() throws IOException { + expectedEvents = new ArrayList<String>(); + InputStream xslt = getClass().getResourceAsStream("extract-events.xsl"); + try { + runXSLT(xslt); + } finally { + closeStream(xslt); + closeStream(document); + } + } + + private void runXSLT(InputStream xslt) { + Transformer transformer = createTransformer(xslt); + Source fo = new StreamSource(document); + Result result = createTransformOutputHandler(); + try { + transformer.transform(fo, result); + } catch (TransformerException e) { + throw new RuntimeException(e); + } + } + + private Transformer createTransformer(InputStream xslt) { + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + try { + return transformerFactory.newTransformer(new StreamSource(xslt)); + } catch (TransformerConfigurationException e) { + throw new RuntimeException(e); + } + } + + private Result createTransformOutputHandler() { + return new SAXResult(new DefaultHandler() { + + private final StringBuilder event = new StringBuilder(); + + @Override + public void startElement(String uri, String localName, String qName, + Attributes attributes) throws SAXException { + event.setLength(0); + } + + @Override + public void characters(char[] ch, int start, int length) throws SAXException { + event.append(ch, start, length); + } + + @Override + public void endElement(String uri, String localName, String qName) throws SAXException { + expectedEvents.add(event.toString()); + } + + }); + } + + private void closeStream(InputStream stream) { + try { + stream.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private void createDocumentParser() { + documentParser = FODocumentParser.newInstance(new FOEventHandlerFactory() { + + public FOEventHandler newFOEventHandler(FOUserAgent foUserAgent) { + return new DelegatingFOEventHandler( + new DelegatingFOEventHandlerTester(foUserAgent)) { + }; + } + }); + } + + @Test + public void testFOEventHandler() throws Exception { + documentParser.parse(document); + assertArrayEquals(expectedEvents.toArray(), actualEvents.toArray()); + } + + @After + public void unloadDocument() throws IOException { + document.close(); + } + + /** + * Prints the given list to {@code System.out}, each element on a new line. For + * debugging purpose. + * + * @param list a list + */ + public void printList(List<?> list) { + for (Object element : list) { + System.out.println(element); + } + } + +} diff --git a/test/java/org/apache/fop/fo/FODocumentParser.java b/test/java/org/apache/fop/fo/FODocumentParser.java new file mode 100644 index 000000000..4706866a4 --- /dev/null +++ b/test/java/org/apache/fop/fo/FODocumentParser.java @@ -0,0 +1,145 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.fo; + +import java.io.InputStream; + +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.sax.SAXResult; +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.apps.FopFactory; +import org.apache.fop.events.EventListener; + +/** + * Parse an FO document and run the corresponding FO events through a given + * {@link FOEventHandler} instance. That instance is created using the helper + * {@link FOEventHandlerFactory}. + * + * <p>An instance of this class may not be used in multiple threads concurrently.<p> + * + * <p>An instance of this class may be used multiple times if the given + * {@link FOEventHandler} implementation can be used multiple times. + */ +public final class FODocumentParser { + + private static final TransformerFactory TRANSFORMER_FACTORY = TransformerFactory.newInstance(); + + private static final FopFactory FOP_FACTORY = FopFactory.newInstance(); + + private final FOEventHandlerFactory foEventHandlerFactory; + + private Fop fop; + + private Transformer transformer; + + private EventListener eventListener; + + /** + * A factory to create custom instances of {@link FOEventHandler}. + */ + public static interface FOEventHandlerFactory { + + /** + * Creates a new {@code FOEventHandler} instance parameterized with the given FO user agent. + * + * @param foUserAgent an FO user agent + * @return a new {@code FOEventHandler} instance + */ + FOEventHandler newFOEventHandler(FOUserAgent foUserAgent); + } + + private FODocumentParser(FOEventHandlerFactory foeEventHandlerFactory) { + this.foEventHandlerFactory = foeEventHandlerFactory; + } + + /** + * Creates and returns a new FO document parser. The given factory will be used to + * customize the handler that will receive FO events, using the + * {@link FOUserAgent#setFOEventHandlerOverride(FOEventHandler)} method. + * + * @param foEventHandlerFactory the factory to be used to create {@code + * FOEventHandler} instances + * @return a new parser + */ + public static FODocumentParser newInstance(FOEventHandlerFactory foEventHandlerFactory) { + return new FODocumentParser(foEventHandlerFactory); + } + + /** + * Sets the event listener to be used if events occurs when parsing the document. + * + * @param eventListener an event listener + */ + public void setEventListener(EventListener eventListener) { + this.eventListener = eventListener; + } + + /** + * Runs FOP on the given document. + * + * @param document XSL-FO document to parse + * @throws FOPException if an error occurs when initializing FOP + * @throws LoadingException if an error occurs when parsing the document + */ + public void parse(InputStream document) throws FOPException, LoadingException { + FOUserAgent foUserAgent = createFOUserAgent(); + fop = FOP_FACTORY.newFop(foUserAgent); + createTransformer(); + runTransformer(document); + } + + private FOUserAgent createFOUserAgent() { + FOUserAgent userAgent = FOP_FACTORY.newFOUserAgent(); + FOEventHandler foEventHandler = foEventHandlerFactory.newFOEventHandler(userAgent); + userAgent.setFOEventHandlerOverride(foEventHandler); + if (eventListener != null) { + userAgent.getEventBroadcaster().addEventListener(eventListener); + } + return userAgent; + } + + private void createTransformer() { + try { + transformer = TRANSFORMER_FACTORY.newTransformer(); + } catch (TransformerConfigurationException e) { + throw new RuntimeException(e); + } + } + + private void runTransformer(InputStream input) throws LoadingException, FOPException { + Source source = new StreamSource(input); + Result result = new SAXResult(fop.getDefaultHandler()); + try { + transformer.transform(source, result); + } catch (TransformerException e) { + Throwable cause = e.getCause(); + throw new LoadingException(cause == null ? e : cause); + } + } +} diff --git a/test/java/org/apache/fop/fo/FONodeMocks.java b/test/java/org/apache/fop/fo/FONodeMocks.java new file mode 100644 index 000000000..1310d4a78 --- /dev/null +++ b/test/java/org/apache/fop/fo/FONodeMocks.java @@ -0,0 +1,88 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.fo; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.IOException; + +import org.apache.xmlgraphics.image.loader.ImageException; +import org.apache.xmlgraphics.image.loader.ImageManager; +import org.apache.xmlgraphics.image.loader.ImageSessionContext; + +import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.apps.FopFactory; + +/** + * A helper class for creating mocks of {@link FONode} and its descendants. + */ +public final class FONodeMocks { + + private FONodeMocks() { } + + /** + * Creates and returns a mock {@link FONode} configured with a mock + * {@link FOEventHandler}. The FO event handler returns a mock {@link FOUserAgent}, + * which in turn returns a mock {@link FopFactory}, which returns a mock + * {@link ImageManager}. + * + * @return a mock FO node + */ + public static FONode mockFONode() { + FONode mockFONode = mock(FONode.class); + mockGetFOEventHandler(mockFONode); + return mockFONode; + } + + private static void mockGetFOEventHandler(FONode mockFONode) { + FOEventHandler mockFOEventHandler = mock(FOEventHandler.class); + mockGetUserAgent(mockFOEventHandler); + when(mockFONode.getFOEventHandler()).thenReturn(mockFOEventHandler); + } + + private static void mockGetUserAgent(FOEventHandler mockFOEventHandler) { + FOUserAgent mockFOUserAgent = mock(FOUserAgent.class); + mockGetFactory(mockFOUserAgent); + when(mockFOEventHandler.getUserAgent()).thenReturn(mockFOUserAgent); + } + + private static void mockGetFactory(FOUserAgent mockFOUserAgent) { + FopFactory mockFopFactory = mock(FopFactory.class); + mockGetImageManager(mockFopFactory); + when(mockFOUserAgent.getFactory()).thenReturn(mockFopFactory); + } + + private static void mockGetImageManager(FopFactory mockFopFactory) { + try { + ImageManager mockImageManager = mock(ImageManager.class); + when(mockImageManager.getImageInfo(anyString(), any(ImageSessionContext.class))) + .thenReturn(null); + when(mockFopFactory.getImageManager()).thenReturn(mockImageManager); + } catch (ImageException e) { + throw new RuntimeException(e); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/test/java/org/apache/fop/fo/LoadingException.java b/test/java/org/apache/fop/fo/LoadingException.java new file mode 100644 index 000000000..a5d509209 --- /dev/null +++ b/test/java/org/apache/fop/fo/LoadingException.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.fo; + +/** + * This class specifies an exceptional condition that occurred while an XSL-FO document + * was being parsed. + */ +public class LoadingException extends Exception { + + private static final long serialVersionUID = 7529029475875542916L; + + LoadingException(Throwable cause) { + super(cause); + } + +} diff --git a/test/java/org/apache/fop/fo/extract-events.xsl b/test/java/org/apache/fop/fo/extract-events.xsl new file mode 100644 index 000000000..8edc0ee49 --- /dev/null +++ b/test/java/org/apache/fop/fo/extract-events.xsl @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xsl:stylesheet version="1.0" + xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + xmlns:fo="http://www.w3.org/1999/XSL/Format" + exclude-result-prefixes="fo"> + + <xsl:output indent="yes" omit-xml-declaration="yes"/> + + <xsl:template match="fo:root"> + <event> + <xsl:text>start root</xsl:text> + </event> + <xsl:apply-templates select="fo:page-sequence"/> + <event> + <xsl:text>end root</xsl:text> + </event> + </xsl:template> + + <xsl:template match="fo:*"> + <xsl:call-template name="process.node"> + <xsl:with-param name="id"> + <xsl:apply-templates select="@id"/> + </xsl:with-param> + </xsl:call-template> + </xsl:template> + + <!-- Those elements do not retrieve the id property. + This will have to be fixed at some point. --> + <xsl:template match="fo:footnote|fo:footnote-body"> + <xsl:call-template name="process.node"/> + </xsl:template> + + <xsl:template name="process.node"> + <xsl:param name="id" select="''"/> + <event> + <xsl:text>start </xsl:text> + <xsl:value-of select="local-name()"/> + <xsl:value-of select="$id"/> + </event> + <xsl:apply-templates/> + <event> + <xsl:text>end </xsl:text> + <xsl:value-of select="local-name()"/> + <xsl:value-of select="$id"/> + </event> + </xsl:template> + + <xsl:template match="@id"> + <xsl:text> id="</xsl:text> + <xsl:value-of select="."/> + <xsl:text>"</xsl:text> + </xsl:template> + + <xsl:template match="text()"/> + +</xsl:stylesheet> diff --git a/test/java/org/apache/fop/fo/flow/table/AbstractTableTestCase.java b/test/java/org/apache/fop/fo/flow/table/AbstractTableTestCase.java index 90d89d702..01e20166a 100644 --- a/test/java/org/apache/fop/fo/flow/table/AbstractTableTestCase.java +++ b/test/java/org/apache/fop/fo/flow/table/AbstractTableTestCase.java @@ -19,33 +19,37 @@ package org.apache.fop.fo.flow.table; +import java.io.FileInputStream; import java.util.Iterator; import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.fo.FODocumentParser; import org.apache.fop.fo.FOEventHandler; -import org.apache.fop.fotreetest.FOTreeUnitTester; +import org.apache.fop.fo.FODocumentParser.FOEventHandlerFactory; +import org.apache.fop.util.ConsoleEventListenerForTests; /** * Superclass for testcases related to tables, factoring the common stuff. */ -abstract class AbstractTableTestCase extends FOTreeUnitTester { +abstract class AbstractTableTestCase { - private FOTreeUnitTester.FOEventHandlerFactory tableHandlerFactory; + private FODocumentParser documentParser; private TableHandler tableHandler; - public AbstractTableTestCase() throws Exception { - super(); - tableHandlerFactory = new FOEventHandlerFactory() { - public FOEventHandler createFOEventHandler(FOUserAgent foUserAgent) { + protected void setUp(String filename) throws Exception { + createDocumentParser(); + documentParser.setEventListener(new ConsoleEventListenerForTests(filename)); + documentParser.parse(new FileInputStream("test/fotree/unittests/" + filename)); + } + + private void createDocumentParser() { + documentParser = FODocumentParser.newInstance(new FOEventHandlerFactory() { + public FOEventHandler newFOEventHandler(FOUserAgent foUserAgent) { tableHandler = new TableHandler(foUserAgent); return tableHandler; } - }; - } - - protected void setUp(String filename) throws Exception { - setUp(filename, tableHandlerFactory); + }); } protected TableHandler getTableHandler() { diff --git a/test/java/org/apache/fop/fo/flow/table/CollapsedConditionalBorderTestCase.java b/test/java/org/apache/fop/fo/flow/table/CollapsedConditionalBorderTestCase.java index 7501c1b9a..d046537e3 100644 --- a/test/java/org/apache/fop/fo/flow/table/CollapsedConditionalBorderTestCase.java +++ b/test/java/org/apache/fop/fo/flow/table/CollapsedConditionalBorderTestCase.java @@ -25,10 +25,11 @@ import java.awt.Color; import java.util.Iterator; import java.util.List; +import org.junit.Test; + import org.apache.fop.fo.Constants; import org.apache.fop.fo.FONode.FONodeIterator; import org.apache.fop.fo.properties.CommonBorderPaddingBackground.BorderInfo; -import org.junit.Test; /** * A testcase for the resolution of collapsed borders in the FO tree, taking @@ -107,10 +108,6 @@ public class CollapsedConditionalBorderTestCase extends AbstractTableTestCase { {{border8pt, Color.black}, {border6pt, Color.blue}, {border8pt, Color.black}, {border6pt, Color.blue}, {border4pt, Color.black}, {border4pt, Color.black}, {border4pt, Color.red}, {border8pt, Color.black}, {border8pt, Color.black}, {border8pt, Color.black}, {border8pt, Color.black}, {border4pt, Color.blue}, {border4pt, Color.red}, {border6pt, Color.magenta}, {border6pt, Color.magenta}, {border6pt, Color.magenta}} }; - public CollapsedConditionalBorderTestCase() throws Exception { - super(); - } - private static GridUnit getGridUnit(TablePart part) { return (GridUnit) ((List) ((List) part.getRowGroups().get(0)).get(0)).get(0); } diff --git a/test/java/org/apache/fop/fo/flow/table/ErrorCheckTestCase.java b/test/java/org/apache/fop/fo/flow/table/ErrorCheckTestCase.java index a3a6b9e71..68c7d9f30 100644 --- a/test/java/org/apache/fop/fo/flow/table/ErrorCheckTestCase.java +++ b/test/java/org/apache/fop/fo/flow/table/ErrorCheckTestCase.java @@ -19,8 +19,10 @@ package org.apache.fop.fo.flow.table; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import org.apache.fop.fo.LoadingException; import org.apache.fop.fo.ValidationException; /** @@ -28,16 +30,13 @@ import org.apache.fop.fo.ValidationException; */ abstract class ErrorCheckTestCase extends AbstractTableTestCase { - public ErrorCheckTestCase() throws Exception { - super(); - } - protected void launchTest(String filename) throws Exception { try { setUp(filename); - fail(); - } catch (ValidationException e) { + fail("Expected ValidationException to be thrown"); + } catch (LoadingException e) { // TODO check location + assertTrue(e.getCause() instanceof ValidationException); } } diff --git a/test/java/org/apache/fop/fo/flow/table/IllegalRowSpanTestCase.java b/test/java/org/apache/fop/fo/flow/table/IllegalRowSpanTestCase.java index 5473f098a..4018f957c 100644 --- a/test/java/org/apache/fop/fo/flow/table/IllegalRowSpanTestCase.java +++ b/test/java/org/apache/fop/fo/flow/table/IllegalRowSpanTestCase.java @@ -27,10 +27,6 @@ import org.junit.Test; */ public class IllegalRowSpanTestCase extends ErrorCheckTestCase { - public IllegalRowSpanTestCase() throws Exception { - super(); - } - @Test public void testBody1() throws Exception { launchTest("table/illegal-row-span_body_1.fo"); diff --git a/test/java/org/apache/fop/fo/flow/table/RowGroupBuilderTestCase.java b/test/java/org/apache/fop/fo/flow/table/RowGroupBuilderTestCase.java index 48c25faca..1af3083ec 100644 --- a/test/java/org/apache/fop/fo/flow/table/RowGroupBuilderTestCase.java +++ b/test/java/org/apache/fop/fo/flow/table/RowGroupBuilderTestCase.java @@ -35,10 +35,6 @@ import org.junit.Test; */ public class RowGroupBuilderTestCase extends AbstractTableTestCase { - public RowGroupBuilderTestCase() throws Exception { - super(); - } - /** * Checks that the given table-body(header,footer) will return row groups as expected. * More precisely, checks that the number of row groups corresponds to the size of the diff --git a/test/java/org/apache/fop/fo/flow/table/TableColumnColumnNumberTestCase.java b/test/java/org/apache/fop/fo/flow/table/TableColumnColumnNumberTestCase.java index 0f24ae68c..c6a93a65c 100644 --- a/test/java/org/apache/fop/fo/flow/table/TableColumnColumnNumberTestCase.java +++ b/test/java/org/apache/fop/fo/flow/table/TableColumnColumnNumberTestCase.java @@ -23,9 +23,10 @@ import static org.junit.Assert.assertEquals; import java.util.Iterator; +import org.junit.Test; + import org.apache.fop.datatypes.PercentBaseContext; import org.apache.fop.fo.FObj; -import org.junit.Test; public class TableColumnColumnNumberTestCase extends AbstractTableTestCase { @@ -50,10 +51,6 @@ public class TableColumnColumnNumberTestCase extends AbstractTableTestCase { private TablePercentBaseContext percentBaseContext = new TablePercentBaseContext(); - public TableColumnColumnNumberTestCase() throws Exception { - super(); - } - private void checkColumn(Table t, int number, boolean isImplicit, int spans, int repeated, int width) { TableColumn c = t.getColumn(number - 1); // TODO a repeated column has a correct number only for its first occurrence diff --git a/test/java/org/apache/fop/fo/flow/table/TooManyColumnsTestCase.java b/test/java/org/apache/fop/fo/flow/table/TooManyColumnsTestCase.java index 665a88759..7a9af100e 100644 --- a/test/java/org/apache/fop/fo/flow/table/TooManyColumnsTestCase.java +++ b/test/java/org/apache/fop/fo/flow/table/TooManyColumnsTestCase.java @@ -23,10 +23,6 @@ import org.junit.Test; public class TooManyColumnsTestCase extends ErrorCheckTestCase { - public TooManyColumnsTestCase() throws Exception { - super(); - } - @Test public void testBody1() throws Exception { launchTest("table/too-many-columns_body_1.fo"); diff --git a/test/java/org/apache/fop/fo/flow/table/UnimplementedWarningNeutralizer.java b/test/java/org/apache/fop/fo/flow/table/UnimplementedWarningNeutralizer.java new file mode 100644 index 000000000..1a5e38291 --- /dev/null +++ b/test/java/org/apache/fop/fo/flow/table/UnimplementedWarningNeutralizer.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.fo.flow.table; + +/** + * This class aims at easing testing, by preventing the event notification system from + * getting in the way just to issue an Unimplemented Feature warning. + */ +public final class UnimplementedWarningNeutralizer { + + private UnimplementedWarningNeutralizer() { } + + /** + * Neutralizes Unimplemented Feature events from the {@link TableAndCaption} and + * {@link TableCaption} classes. + */ + public static void neutralizeUnimplementedWarning() { + TableAndCaption.notImplementedWarningGiven = true; + TableCaption.notImplementedWarningGiven = true; + } +} diff --git a/test/java/org/apache/fop/fo/properties/AltTextHolderTestCase.java b/test/java/org/apache/fop/fo/properties/AltTextHolderTestCase.java new file mode 100644 index 000000000..cd5d545ff --- /dev/null +++ b/test/java/org/apache/fop/fo/properties/AltTextHolderTestCase.java @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.fo.properties; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.junit.Test; + +import org.apache.fop.apps.FOPException; +import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.fo.Constants; +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FONodeMocks; +import org.apache.fop.fo.PropertyList; +import org.apache.fop.fo.expr.PropertyException; +import org.apache.fop.fo.flow.AbstractGraphics; +import org.apache.fop.fo.flow.ExternalGraphic; +import org.apache.fop.fo.flow.InstreamForeignObject; + + +/** + * Tests that the fox:alt-text property is correctly set on objects that support it. + */ +public class AltTextHolderTestCase { + + private final String altText = "alternative text"; + + @Test + public void externalGraphicHasAltText() throws FOPException { + testAltTextGetter(new ExternalGraphic(mockFONode())); + } + + @Test + public void instreamForeignObjectHasAltText() throws FOPException { + testAltTextGetter(new InstreamForeignObject(mockFONode())); + } + + private FONode mockFONode() { + FONode mockFONode = FONodeMocks.mockFONode(); + FOUserAgent mockFOUserAgent = mockFONode.getFOEventHandler().getUserAgent(); + when(mockFOUserAgent.isAccessibilityEnabled()).thenReturn(true); + return mockFONode; + } + + private void testAltTextGetter(AbstractGraphics g) throws FOPException { + g.bind(mockPropertyList()); + assertEquals(altText, g.getAltText()); + } + + private PropertyList mockPropertyList() throws PropertyException { + PropertyList mockPropertyList = PropertyListMocks.mockPropertyList(); + Property mockAltText = mock(Property.class); + when(mockAltText.getString()).thenReturn(altText); + when(mockPropertyList.get(Constants.PR_X_ALT_TEXT)).thenReturn(mockAltText); + return mockPropertyList; + } + +} diff --git a/test/java/org/apache/fop/fo/properties/CommonAccessibilityHolderTestCase.java b/test/java/org/apache/fop/fo/properties/CommonAccessibilityHolderTestCase.java new file mode 100644 index 000000000..45f6a61ab --- /dev/null +++ b/test/java/org/apache/fop/fo/properties/CommonAccessibilityHolderTestCase.java @@ -0,0 +1,127 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.fo.properties; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.lang.reflect.Constructor; +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +import org.apache.fop.fo.Constants; +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.FONodeMocks; +import org.apache.fop.fo.PropertyList; +import org.apache.fop.fo.expr.PropertyException; + +/** + * This tests that all the FONodes that implement CommonAccessibilityHolder correctly configure + * the CommonAccessibility property. + */ +public class CommonAccessibilityHolderTestCase { + + private static final List<Class<? extends CommonAccessibilityHolder>> IMPLEMENTATIONS + = new ArrayList<Class<? extends CommonAccessibilityHolder>>(); + + private final String role = "role"; + + private final String sourceDocument = "source document"; + + static { + /* This triggers 'unimplemented feature' FO validation events so that the event system is + * not triggered when testing, avoiding extra convoluted dependency stubbing. */ +// UnimplementedWarningNeutralizer.neutralizeUnimplementedWarning(); + + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.BasicLink.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.Block.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.pagination.bookmarks.Bookmark.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.pagination.bookmarks.BookmarkTitle.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.ExternalGraphic.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.Footnote.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.FootnoteBody.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.InitialPropertySet.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.Inline.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.InstreamForeignObject.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.Leader.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.ListBlock.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.ListItem.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.ListItemBody.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.ListItemLabel.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.PageNumber.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.PageNumberCitation.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.PageNumberCitationLast.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.pagination.Root.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.table.Table.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.table.TableAndCaption.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.table.TableBody.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.table.TableCaption.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.table.TableCell.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.table.TableFooter.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.table.TableHeader.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.flow.table.TableRow.class); + IMPLEMENTATIONS.add(org.apache.fop.fo.pagination.Title.class); + } + + /** + * Bind should be overridden to correctly configure the CommonAccessibility property + * @throws Exception - + */ + @Test + public void bindMustSetRoleAndSourceDoc() throws Exception { + final PropertyList mockPList = mockPropertyList(); + final FONode parent = FONodeMocks.mockFONode(); + for (Class<? extends CommonAccessibilityHolder> clazz : IMPLEMENTATIONS) { + Constructor<? extends CommonAccessibilityHolder> constructor + = clazz.getConstructor(FONode.class); + CommonAccessibilityHolder sut = constructor.newInstance(parent); + ((FONode)sut).bind(mockPList); + String errorMessage = "Test failed for " + clazz + ": "; + assertEquals(errorMessage, role, sut.getCommonAccessibility().getRole()); + assertEquals(errorMessage, sourceDocument, + sut.getCommonAccessibility().getSourceDocument()); + } + } + + private PropertyList mockPropertyList() throws PropertyException { + final PropertyList mockPList = PropertyListMocks.mockPropertyList(); + PropertyListMocks.mockTableProperties(mockPList); + PropertyListMocks.mockCommonBorderPaddingBackgroundProps(mockPList); + mockRoleProperty(mockPList); + mockSourceDocProperty(mockPList); + return mockPList; + } + + private void mockRoleProperty(PropertyList mockPList) throws PropertyException { + final Property mockRoleProperty = mock(Property.class); + when(mockRoleProperty.getString()).thenReturn(role); + when(mockPList.get(Constants.PR_ROLE)).thenReturn(mockRoleProperty); + } + + private void mockSourceDocProperty(PropertyList mockPList) throws PropertyException { + final Property mockSourceDocProperty = mock(Property.class); + when(mockSourceDocProperty.getString()).thenReturn(sourceDocument); + when(mockPList.get(Constants.PR_SOURCE_DOCUMENT)).thenReturn(mockSourceDocProperty); + } + +} diff --git a/test/java/org/apache/fop/fo/properties/PropertyListMocks.java b/test/java/org/apache/fop/fo/properties/PropertyListMocks.java new file mode 100644 index 000000000..380f6e5a8 --- /dev/null +++ b/test/java/org/apache/fop/fo/properties/PropertyListMocks.java @@ -0,0 +1,94 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.fo.properties; + +import static org.mockito.Matchers.anyInt; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.apache.fop.fo.Constants; +import org.apache.fop.fo.PropertyList; +import org.apache.fop.fo.expr.PropertyException; + +/** + * A helper class for mocking a property list. + */ +public final class PropertyListMocks { + + private PropertyListMocks() { } + + /** + * Creates and returns a mock property list returning a generic default for the + * {@link PropertyList#get(int)} method. + * + * @return a mock property list + */ + public static PropertyList mockPropertyList() { + try { + final PropertyList mockPList = mock(PropertyList.class); + final Property mockGenericProperty = PropertyMocks.mockGenericProperty(); + when(mockPList.get(anyInt())).thenReturn(mockGenericProperty); + return mockPList; + } catch (PropertyException e) { + throw new RuntimeException(e); + } + } + + /** + * Overrides with working mock properties the values returned by + * {@link PropertyList#get(int)} for {@link Constants#PR_COLUMN_NUMBER}, + * {@link Constants#PR_NUMBER_COLUMNS_SPANNED}, + * {@link Constants#PR_NUMBER_ROWS_SPANNED} and {@link Constants#PR_BORDER_COLLAPSE}. + * + * @param mockPList a mock property list + */ + public static void mockTableProperties(PropertyList mockPList) { + try { + final Property mockNumberProperty = PropertyMocks.mockNumberProperty(); + when(mockPList.get(Constants.PR_COLUMN_NUMBER)).thenReturn(mockNumberProperty); + when(mockPList.get(Constants.PR_NUMBER_COLUMNS_SPANNED)).thenReturn(mockNumberProperty); + when(mockPList.get(Constants.PR_NUMBER_ROWS_SPANNED)).thenReturn(mockNumberProperty); + + final Property borderCollapseProperty = mock(Property.class); + when(borderCollapseProperty.getEnum()).thenReturn(Constants.EN_SEPARATE); + when(mockPList.get(Constants.PR_BORDER_COLLAPSE)).thenReturn(borderCollapseProperty); + } catch (PropertyException e) { + throw new RuntimeException(e); + } + } + + /** + * Overrides with a working mock property the value returned by + * {@link PropertyList#getBorderPaddingBackgroundProps()}. + * + * @param mockPList a mock property list + */ + public static void mockCommonBorderPaddingBackgroundProps(PropertyList mockPList) { + try { + final CommonBorderPaddingBackground mockCommonBorderPaddingBackground + = mock(CommonBorderPaddingBackground.class); + when(mockPList.getBorderPaddingBackgroundProps()) + .thenReturn(mockCommonBorderPaddingBackground); + } catch (PropertyException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/test/java/org/apache/fop/fo/properties/PropertyMocks.java b/test/java/org/apache/fop/fo/properties/PropertyMocks.java new file mode 100644 index 000000000..40c923249 --- /dev/null +++ b/test/java/org/apache/fop/fo/properties/PropertyMocks.java @@ -0,0 +1,80 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.fo.properties; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.apache.fop.datatypes.Numeric; +import org.apache.fop.datatypes.PercentBaseContext; +import org.apache.fop.fo.Constants; + +/** + * Helper class to create mocks of various kinds of properties. + */ +public final class PropertyMocks { + + private PropertyMocks() { } + + /** + * Creates and returns a generic mock property returning decent defaults for the + * {@link Property#getString()}, {@link Property#getEnum()} and + * {@link Property#getLengthRange()} methods. + * + * @return a mock all-purpose property + */ + public static Property mockGenericProperty() { + final Property mockGenericProperty = mock(Property.class); + when(mockGenericProperty.getString()).thenReturn("A non-empty string"); + when(mockGenericProperty.getEnum()).thenReturn(Constants.EN_SPACE); + LengthRangeProperty lengthRangeProperty = mockLengthRangeProperty(); + when(mockGenericProperty.getLengthRange()).thenReturn(lengthRangeProperty); + return mockGenericProperty; + } + + private static LengthRangeProperty mockLengthRangeProperty() { + final LengthRangeProperty mockLengthRangeProperty = mock(LengthRangeProperty.class); + final Property optimum = mockOptimumProperty(); + when(mockLengthRangeProperty.getOptimum(any(PercentBaseContext.class))) + .thenReturn(optimum); + return mockLengthRangeProperty; + } + + /** + * Creates and returns a mock property returning a decent default for the + * {@link Property#getNumeric()} method. + * + * @return a mock number property + */ + public static Property mockNumberProperty() { + final Property mockNumberProperty = mock(Property.class); + final Numeric mockNumeric = mock(Numeric.class); + when(mockNumberProperty.getNumeric()).thenReturn(mockNumeric); + return mockNumberProperty; + } + + private static Property mockOptimumProperty() { + final Property optimum = mock(Property.class); + when(optimum.isAuto()).thenReturn(true); + return optimum; + } + +} diff --git a/test/java/org/apache/fop/fotreetest/FOTreeTestSuite.java b/test/java/org/apache/fop/fotreetest/FOTreeTestSuite.java index 6e6f62b92..b43576901 100644 --- a/test/java/org/apache/fop/fotreetest/FOTreeTestSuite.java +++ b/test/java/org/apache/fop/fotreetest/FOTreeTestSuite.java @@ -19,20 +19,29 @@ package org.apache.fop.fotreetest; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +import org.apache.fop.fo.DelegatingFOEventHandlerTestCase; import org.apache.fop.fo.flow.table.CollapsedConditionalBorderTestCase; import org.apache.fop.fo.flow.table.IllegalRowSpanTestCase; import org.apache.fop.fo.flow.table.RowGroupBuilderTestCase; import org.apache.fop.fo.flow.table.TableColumnColumnNumberTestCase; import org.apache.fop.fo.flow.table.TooManyColumnsTestCase; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; /** * JUnit test suit for running layout engine test under JUnit control. */ @RunWith(Suite.class) -@Suite.SuiteClasses({ TooManyColumnsTestCase.class, IllegalRowSpanTestCase.class, - RowGroupBuilderTestCase.class, TableColumnColumnNumberTestCase.class, - CollapsedConditionalBorderTestCase.class, FOTreeTester.class }) +@Suite.SuiteClasses({ + TooManyColumnsTestCase.class, + IllegalRowSpanTestCase.class, + RowGroupBuilderTestCase.class, + TableColumnColumnNumberTestCase.class, + CollapsedConditionalBorderTestCase.class, + FOTreeTester.class, + org.apache.fop.fo.properties.CommonAccessibilityHolderTestCase.class, + DelegatingFOEventHandlerTestCase.class +}) public final class FOTreeTestSuite { } diff --git a/test/java/org/apache/fop/fotreetest/FOTreeUnitTester.java b/test/java/org/apache/fop/fotreetest/FOTreeUnitTester.java deleted file mode 100644 index 0906c266d..000000000 --- a/test/java/org/apache/fop/fotreetest/FOTreeUnitTester.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.fotreetest; - -import java.io.File; - -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; - -import org.apache.fop.apps.FOUserAgent; -import org.apache.fop.apps.Fop; -import org.apache.fop.apps.FopFactory; -import org.apache.fop.fo.FOEventHandler; -import org.apache.fop.util.ConsoleEventListenerForTests; -import org.xml.sax.XMLReader; - - -/** - * Base class for unit-testing the FO tree building code. It performs the necessary setup - * to parse an FO file and register a proper {@link FOEventHandler}. That handler will be - * the entry point to test classes from the FObj hierarchy. - */ -public abstract class FOTreeUnitTester { - - private XMLReader foReader; - - private FopFactory fopFactory; - - /** - * Should be implemented by children testcases for properly setting up the custom - * FOEventHandler needed to test FObj classes. - */ - public abstract static class FOEventHandlerFactory { - - /** - * This method is called by FOTreeUnitTester when creating a {@link Fop} instance. - * That lets pass to the custom FOEventHandler the proper user agent that will be - * used by this instance. - * - * @param foUserAgent the user agent needed by the Fop instance that will be used - * to create the FO tree - * @return the appropriate FOEventHandler for performing the tests - */ - public abstract FOEventHandler createFOEventHandler(FOUserAgent foUserAgent); - } - - public FOTreeUnitTester() throws Exception { - // Stuff that needs to be set up only once and will be re-used for each test - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - spf.setValidating(false); - SAXParser parser; - parser = spf.newSAXParser(); - foReader = parser.getXMLReader(); - fopFactory = FopFactory.newInstance(); - } - - /** - * Launches FOP on the given FO file. - * - * @param filename path to the test FO file - * @param factory to create the appropriate FOEventHandler for performing tests - */ - public void setUp(String filename, FOEventHandlerFactory factory) throws Exception { - FOUserAgent ua = fopFactory.newFOUserAgent(); - ua.setFOEventHandlerOverride(factory.createFOEventHandler(ua)); - ua.getEventBroadcaster().addEventListener( - new ConsoleEventListenerForTests(filename)); - - Fop fop = fopFactory.newFop(ua); - - foReader.setContentHandler(fop.getDefaultHandler()); - foReader.setDTDHandler(fop.getDefaultHandler()); - foReader.setErrorHandler(fop.getDefaultHandler()); - foReader.setEntityResolver(fop.getDefaultHandler()); - - foReader.parse(new File("test/fotree/unittests/" + filename).toURI().toURL().toExternalForm()); - } -} |