stephan 2003/01/27 12:07:16 Modified: . build.xml tools/lib excalibur-testcase-1.0.jar Added: src/test/org/apache/cocoon/components/source SourceResolverAdapter.java src/test/org/apache/cocoon/generation AbstractGeneratorTestCase.java FileGeneratorTestCase.java FileGeneratorTestCase.source.xml FileGeneratorTestCase.xtest src/test/org/apache/cocoon/transformation AbstractTransformerTestCase.java src/test/org/apache/cocoon/xml WhitespaceFilter.java tools/lib xmlunit0.8.jar Log: Add abstract test cases for generators and transformers, which allows to test these components outside of the cocoon enviroment. Revision Changes Path 1.312 +3 -2 xml-cocoon2/build.xml Index: build.xml =================================================================== RCS file: /home/cvs/xml-cocoon2/build.xml,v retrieving revision 1.311 retrieving revision 1.312 diff -u -r1.311 -r1.312 --- build.xml 25 Jan 2003 12:58:20 -0000 1.311 +++ build.xml 27 Jan 2003 20:07:14 -0000 1.312 @@ -2311,10 +2311,11 @@ <formatter type="plain" usefile="no" /> <batchtest> <fileset dir="${build.test}"> - <include name="**/test/*TestCase.class"/> + <include name="**/*TestCase.class"/> <include name="**/*Test.class" /> <exclude name="**/AllTest.class" /> <exclude name="**/*$$*Test.class" /> + <exclude name="**/Abstract*.class" /> </fileset> </batchtest> </junit> 1.1 xml-cocoon2/src/test/org/apache/cocoon/components/source/SourceResolverAdapter.java Index: SourceResolverAdapter.java =================================================================== /* ============================================================================ The Apache Software License, Version 1.1 ============================================================================ Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modifica- tion, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The end-user documentation included with the redistribution, if any, must include the following acknowledgment: "This product includes software developed by the Apache Software Foundation (http://www.apache.org/)." Alternately, this acknowledgment may appear in the software itself, if and wherever such third-party acknowledgments normally appear. 4. The names "Apache Cocoon" and "Apache Software Foundation" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact [EMAIL PROTECTED] 5. Products derived from this software may not be called "Apache", nor may "Apache" appear in their name, without prior written permission of the Apache Software Foundation. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the Apache Software Foundation and was originally created by Stefano Mazzocchi <[EMAIL PROTECTED]>. For more information on the Apache Software Foundation, please see <http://www.apache.org/>. */ package org.apache.cocoon.components.source; import java.io.IOException; import java.net.MalformedURLException; import java.util.Map; import org.apache.avalon.framework.component.Component; import org.apache.avalon.framework.component.ComponentException; import org.apache.avalon.framework.component.ComponentManager; import org.apache.cocoon.components.source.impl.AvalonToCocoonSource; import org.apache.cocoon.environment.SourceResolver; import org.apache.cocoon.environment.Source; import org.apache.cocoon.ProcessingException; import org.apache.excalibur.xml.sax.SAXParser; import org.xml.sax.ContentHandler; import org.xml.sax.InputSource; import org.xml.sax.SAXException; public class SourceResolverAdapter implements SourceResolver { private org.apache.excalibur.source.SourceResolver resolver; private ComponentManager manager; public SourceResolverAdapter(org.apache.excalibur.source.SourceResolver resolver, ComponentManager manager) { this.resolver = resolver; this.manager = manager; } /** * Get a <code>Source</code> object. * This is a shortcut for <code>resolve(location, null, null)</code> * @throws SourceNotFoundException if the source cannot be found */ public org.apache.excalibur.source.Source resolveURI( String location ) throws MalformedURLException, IOException, org.apache.excalibur.source.SourceException { return this.resolver.resolveURI(location); } /** * Get a <code>Source</code> object. * @param location - the URI to resolve. If this is relative it is either * resolved relative to the base parameter (if not null) * or relative to a base setting of the source resolver * itself. * @param base - a base URI for resolving relative locations. This * is optional and can be <code>null</code>. * @param parameters - Additional parameters for the URI. The parameters * are specific to the used protocol. * @throws SourceNotFoundException if the source cannot be found */ public org.apache.excalibur.source.Source resolveURI( String location, String base, Map parameters ) throws MalformedURLException, IOException, org.apache.excalibur.source.SourceException { return this.resolver.resolveURI(location, base, parameters); } /** * Releases a resolved resource */ public void release( org.apache.excalibur.source.Source source ) { this.resolver.release(source); } /** * Resolve the source. * @param systemID This is either a system identifier * (<code>java.net.URL</code> or a local file. * @deprecated Use the resolveURI methods instead */ public Source resolve(String systemID) throws ProcessingException, SAXException, IOException { try { return new AvalonToCocoonSource(this.resolver.resolveURI(systemID), this.resolver, null); } catch (org.apache.excalibur.source.SourceException se) { throw new ProcessingException(se.toString()); } } /** * Generates SAX events from the given source * <b>NOTE</b> : if the implementation can produce lexical events, care should be taken * that <code>handler</code> can actually * directly implement the LexicalHandler interface! * @param source the data * @throws ProcessingException if no suitable converter is found */ public void toSAX( org.apache.excalibur.source.Source source, ContentHandler handler ) throws SAXException, IOException, ProcessingException { SAXParser parser = null; Source assertionsource = null; try { parser = (SAXParser) this.manager.lookup(SAXParser.ROLE); parser.parse(new InputSource(source.getInputStream()), handler); } catch (ComponentException ce) { throw new ProcessingException("Couldn't xmlize source", ce); } catch (org.apache.excalibur.source.SourceException se) { throw new ProcessingException("Couldn't xmlize source", se); } finally { this.manager.release((Component) parser); } } } 1.1 xml-cocoon2/src/test/org/apache/cocoon/generation/AbstractGeneratorTestCase.java Index: AbstractGeneratorTestCase.java =================================================================== /* ============================================================================ The Apache Software License, Version 1.1 ============================================================================ Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modifica- tion, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The end-user documentation included with the redistribution, if any, must include the following acknowledgment: "This product includes software developed by the Apache Software Foundation (http://www.apache.org/)." Alternately, this acknowledgment may appear in the software itself, if and wherever such third-party acknowledgments normally appear. 4. The names "Apache Cocoon" and "Apache Software Foundation" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact [EMAIL PROTECTED] 5. Products derived from this software may not be called "Apache", nor may "Apache" appear in their name, without prior written permission of the Apache Software Foundation. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the Apache Software Foundation and was originally created by Stefano Mazzocchi <[EMAIL PROTECTED]>. For more information on the Apache Software Foundation, please see <http://www.apache.org/>. */ package org.apache.cocoon.generation; import java.io.IOException; import java.util.Enumeration; import java.util.Map; import java.util.Vector; import org.apache.excalibur.xml.sax.SAXParser; import org.apache.excalibur.source.Source; import org.apache.excalibur.source.SourceException; import org.apache.excalibur.source.SourceResolver; import org.apache.avalon.excalibur.testcase.ExcaliburTestCase; import org.apache.avalon.framework.component.Component; import org.apache.avalon.framework.component.ComponentException; import org.apache.avalon.framework.component.ComponentSelector; import org.apache.avalon.framework.parameters.Parameters; import org.apache.cocoon.ProcessingException; import org.apache.cocoon.generation.Generator; import org.apache.cocoon.components.source.SourceResolverAdapter; import org.apache.cocoon.xml.WhitespaceFilter; import org.apache.cocoon.xml.dom.DOMBuilder; import org.custommonkey.xmlunit.Diff; import org.w3c.dom.Document; import org.xml.sax.ContentHandler; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.ext.LexicalHandler; /** * Testcase for generator components. It tests the generator * by comparing the output with asserted documents. * * @author <a href="mailto:[EMAIL PROTECTED]">Stephan Michels</a> * @version CVS $Id: AbstractGeneratorTestCase.java,v 1.1 2003/01/27 20:07:15 stephan Exp $ */ public abstract class AbstractGeneratorTestCase extends ExcaliburTestCase { /** If the result document should be equal. */ public final static int EQUAL = 0; /** If the result document should not be equal. */ public final static int NOTEQUAL = 1; /** If the result document should be identical. */ public final static int IDENTICAL = 2; /** If the result document should not be identical. */ public final static int NOTIDENTICAL = 3; private Vector teststeps = new Vector(); /** * Create a new generator test case. * * @param name Name of test case. */ public AbstractGeneratorTestCase(String name) { super(name); } /** * Add a new test step to the test case. * * @param generator Hint of the generator. * @param objectmodel Object model. * @param source Source for the transformer. * @param parameters Generator parameters. * @param assertion Assertion XML document. * @param assertiontype (EQUAL|NOTEQUAL|IDENTICAL|NOTIDENTICAL) */ public final void addTestStep(String generator, Map objectmodel, String source, Parameters parameters, String assertion, int assertiontype) { TestStep test = new TestStep(); test.generator = generator; test.objectmodel = objectmodel; test.source = source; test.parameters = parameters; test.assertion = assertion; test.assertiontype = assertiontype; teststeps.addElement(test); } /** * Test the generators and his output */ public final void testGenerator() { ComponentSelector selector = null; Generator generator = null; SourceResolver resolver = null; SAXParser parser = null; Source assertionsource = null; try { selector = (ComponentSelector) this.manager.lookup(Generator.ROLE+ "Selector"); assertNotNull("Test lookup of generator selector", selector); resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE); assertNotNull("Test lookup of source resolver", resolver); parser = (SAXParser) this.manager.lookup(SAXParser.ROLE); assertNotNull("Test lookup of parser", parser); TestStep test; int count = 0; for (Enumeration e = teststeps.elements(); e.hasMoreElements(); ) { test = (TestStep) e.nextElement(); count++; getLogger().info(count+".Test step"); assertNotNull("Test if generator name is not null", test.generator); generator = (Generator) selector.select(test.generator); assertNotNull("Test lookup of generator", generator); DOMBuilder builder = new DOMBuilder(); if ((test.assertiontype==EQUAL) || (test.assertiontype==NOTEQUAL)) { generator.setConsumer(new WhitespaceFilter(builder)); } else { generator.setConsumer(builder); } generator.setup(new SourceResolverAdapter(resolver, this.manager), test.objectmodel, test.source, test.parameters); generator.generate(); Document document = builder.getDocument(); assertNotNull("Test for generator document", document); assertNotNull("Test if assertion document is not null", test.assertion); assertionsource = resolver.resolveURI(test.assertion); assertNotNull("Test lookup of assertion source", assertionsource); builder = new DOMBuilder(); assertNotNull("Test if inputstream of the assertion source is not null", assertionsource.getInputStream()); if ((test.assertiontype==EQUAL) || (test.assertiontype==NOTEQUAL)) { parser.parse(new InputSource(assertionsource.getInputStream()), (ContentHandler) new WhitespaceFilter(builder), (LexicalHandler) builder); } else { parser.parse(new InputSource(assertionsource.getInputStream()), (ContentHandler) builder, (LexicalHandler) builder); } Document assertiondocument = builder.getDocument(); assertNotNull("Test if assertion document exists", resolver); assertTrue("Test if assertion type is correct", (test.assertiontype>=EQUAL) && (test.assertiontype<=NOTIDENTICAL)); switch (test.assertiontype) { case EQUAL : document.getDocumentElement().normalize(); assertiondocument.getDocumentElement().normalize(); assertXMLEqual(compareXML(assertiondocument, document), true, "Test if the assertion document is equal"); break; case NOTEQUAL : document.getDocumentElement().normalize(); assertiondocument.getDocumentElement().normalize(); assertXMLEqual(compareXML(assertiondocument, document), false, "Test if the assertion document is not equal"); break; case IDENTICAL : assertXMLIdentical(compareXML(assertiondocument, document), true, "Test if the assertion document is identical"); break; case NOTIDENTICAL : assertXMLIdentical(compareXML(assertiondocument, document), false, "Test if the assertion document is not identical"); break; } selector.release(generator); generator = null; resolver.release(assertionsource); assertionsource = null; } } catch (ComponentException ce) { getLogger().error("Could not retrieve generator", ce); fail("Could not retrieve generator:"+ce.toString()); } catch (SAXException saxe) { getLogger().error("Could not execute test", saxe); fail("Could not execute test:"+saxe.toString()); } catch (IOException ioe) { getLogger().error("Could not execute test", ioe); fail("Could not execute test:"+ioe.toString()); } catch (SourceException se) { getLogger().error("Could not retrieve sources", se); fail("Could not retrieve sources:"+se.toString()); } catch (ProcessingException pe) { getLogger().error("Could not execute test", pe); pe.printStackTrace(); fail("Could not execute test:"+pe.toString()); } finally { if (generator!=null) { selector.release(generator); } this.manager.release(selector); this.manager.release(resolver); resolver.release(assertionsource); this.manager.release((Component) parser); } } /** * Compare two XML documents provided as strings * @param control Control document * @param test Document to test * @return Diff object describing differences in documents */ public final Diff compareXML(Document control, Document test) { return new Diff(control, test); } /** * Assert that the result of an XML comparison is or is not similar. * @param diff the result of an XML comparison * @param assertion true if asserting that result is similar */ public final void assertXMLEqual(Diff diff, boolean assertion) { assertEquals(diff.toString(), assertion, diff.similar()); } /** * Assert that the result of an XML comparison is or is not similar. * @param diff the result of an XML comparison * @param assertion true if asserting that result is similar * @param msg additional message to display if assertion fails */ public final void assertXMLEqual(Diff diff, boolean assertion, String msg) { assertEquals(msg+", "+diff.toString(), assertion, diff.similar()); } /** * Assert that the result of an XML comparison is or is not identical * @param diff the result of an XML comparison * @param assertion true if asserting that result is identical */ public final void assertXMLIdentical(Diff diff, boolean assertion) { assertEquals(diff.toString(), assertion, diff.identical()); } /** * Assert that the result of an XML comparison is or is not identical * @param diff the result of an XML comparison * @param assertion true if asserting that result is identical * @param msg additional message to display if assertion fails */ public final void assertXMLIdentical(Diff diff, boolean assertion, String msg) { assertEquals(msg+", "+diff.toString(), assertion, diff.identical()); } /** * Inner class for a test step. */ private class TestStep { /** Hint of the generator. */ public String generator = null; /** Object model. */ public Map objectmodel = null; /** Source for the transformer. */ public String source = null; /** Generator parameters. */ public Parameters parameters = null; /** Assertion XML document. */ public String assertion = null; /** (EQUAL|NOTEQUAL|IDENTICAL|NOTIDENTICAL) */ public int assertiontype = EQUAL; } } 1.1 xml-cocoon2/src/test/org/apache/cocoon/generation/FileGeneratorTestCase.java Index: FileGeneratorTestCase.java =================================================================== /* ============================================================================ The Apache Software License, Version 1.1 ============================================================================ Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modifica- tion, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The end-user documentation included with the redistribution, if any, must include the following acknowledgment: "This product includes software developed by the Apache Software Foundation (http://www.apache.org/)." Alternately, this acknowledgment may appear in the software itself, if and wherever such third-party acknowledgments normally appear. 4. The names "Apache Cocoon" and "Apache Software Foundation" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact [EMAIL PROTECTED] 5. Products derived from this software may not be called "Apache", nor may "Apache" appear in their name, without prior written permission of the Apache Software Foundation. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the Apache Software Foundation and was originally created by Stefano Mazzocchi <[EMAIL PROTECTED]>. For more information on the Apache Software Foundation, please see <http://www.apache.org/>. */ package org.apache.cocoon.generation; import java.io.InputStream; import java.io.IOException; import java.util.HashMap; import org.apache.avalon.framework.parameters.Parameters; public class FileGeneratorTestCase extends AbstractGeneratorTestCase { public FileGeneratorTestCase(String name) { super(name==null?"FileGenerator Testcase":name); String generator = "file"; HashMap objectmodel = new HashMap(); String src = "resource://org/apache/cocoon/generation/FileGeneratorTestCase.source.xml"; Parameters parameters = new Parameters(); String result = "resource://org/apache/cocoon/generation/FileGeneratorTestCase.source.xml"; addTestStep(generator, objectmodel, src, parameters, result, EQUAL); } } 1.1 xml-cocoon2/src/test/org/apache/cocoon/generation/FileGeneratorTestCase.source.xml Index: FileGeneratorTestCase.source.xml =================================================================== <a> <b>bla bla bla</b> <c xmlns="http://xml.apache.org/cocoon/schema/bla/1.0"> <d>bla</d> </c> </a> 1.1 xml-cocoon2/src/test/org/apache/cocoon/generation/FileGeneratorTestCase.xtest Index: FileGeneratorTestCase.xtest =================================================================== <?xml version="1.0" ?> <testcase> <annotation> Test Cases: FileGenerator </annotation> <logkit> <factories> <factory type="file" class="org.apache.avalon.excalibur.logger.factory.FileTargetFactory"/> </factories> <targets> <file id="root"> <filename>cocoon-filegenerator.log</filename> <format type="extended"> %7.7{priority} %5.5{time} [%8.8{category}] (%{context}): %{message}\n%{throwable} </format> </file> </targets> <categories> <category name="test" log-level="DEBUG"> <log-target id-ref="root"/> </category> </categories> </logkit> <context/> <roles> <role name="org.apache.excalibur.xml.sax.SAXParser" shorthand="xml-parser" default-class="org.apache.excalibur.xml.impl.JaxpParser"/> <role name="org.apache.excalibur.source.SourceFactorySelector" shorthand="source-factories" default-class="org.apache.avalon.excalibur.component.ExcaliburComponentSelector"/> <role name="org.apache.excalibur.source.SourceResolver" shorthand="source-resolver" default-class="org.apache.excalibur.source.impl.SourceResolverImpl"/> <role name="org.apache.cocoon.generation.GeneratorSelector" shorthand="generators" default-class="org.apache.cocoon.sitemap.DefaultSitemapComponentSelector"/> </roles> <components> <xml-parser class="org.apache.excalibur.xml.impl.JaxpParser"> <parameter name="validate" value="false"/> <parameter name="namespace-prefixes" value="false"/> <parameter name="stop-on-warning" value="true"/> <parameter name="stop-on-recoverable-error" value="true"/> <parameter name="reuse-parsers" value="false"/> </xml-parser> <source-factories> <component-instance class="org.apache.excalibur.source.impl.ResourceSourceFactory" name="resource"/> </source-factories> <source-resolver class="org.apache.excalibur.source.impl.SourceResolverImpl"/> <generators> <component-instance class="org.apache.cocoon.generation.FileGenerator" name="file"/> </generators> </components> </testcase> 1.1 xml-cocoon2/src/test/org/apache/cocoon/transformation/AbstractTransformerTestCase.java Index: AbstractTransformerTestCase.java =================================================================== /* ============================================================================ The Apache Software License, Version 1.1 ============================================================================ Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modifica- tion, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The end-user documentation included with the redistribution, if any, must include the following acknowledgment: "This product includes software developed by the Apache Software Foundation (http://www.apache.org/)." Alternately, this acknowledgment may appear in the software itself, if and wherever such third-party acknowledgments normally appear. 4. The names "Apache Cocoon" and "Apache Software Foundation" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact [EMAIL PROTECTED] 5. Products derived from this software may not be called "Apache", nor may "Apache" appear in their name, without prior written permission of the Apache Software Foundation. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the Apache Software Foundation and was originally created by Stefano Mazzocchi <[EMAIL PROTECTED]>. For more information on the Apache Software Foundation, please see <http://www.apache.org/>. */ package org.apache.cocoon.transformation; import java.io.IOException; import java.util.Enumeration; import java.util.Map; import java.util.Vector; import org.apache.excalibur.xml.sax.SAXParser; import org.apache.excalibur.source.Source; import org.apache.excalibur.source.SourceException; import org.apache.excalibur.source.SourceResolver; import org.apache.avalon.excalibur.testcase.ExcaliburTestCase; import org.apache.avalon.framework.component.Component; import org.apache.avalon.framework.component.ComponentException; import org.apache.avalon.framework.component.ComponentSelector; import org.apache.avalon.framework.parameters.Parameters; import org.apache.cocoon.ProcessingException; import org.apache.cocoon.transformation.Transformer; import org.apache.cocoon.components.source.SourceResolverAdapter; import org.apache.cocoon.xml.WhitespaceFilter; import org.apache.cocoon.xml.dom.DOMBuilder; import org.custommonkey.xmlunit.Diff; import org.custommonkey.xmlunit.XMLUnit; import org.w3c.dom.Document; import org.w3c.dom.NodeList; import org.xml.sax.ContentHandler; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.ext.LexicalHandler; /** * Testcase for transformer components. It uses multiple input documents * and compares the output with asserted documents. * * @author <a href="mailto:[EMAIL PROTECTED]">Stephan Michels</a> * @version CVS $Id: AbstractTransformerTestCase.java,v 1.1 2003/01/27 20:07:15 stephan Exp $ */ public abstract class AbstractTransformerTestCase extends ExcaliburTestCase { /** If the result document should be equal. */ public final static int EQUAL = 0; /** If the result document should not be equal. */ public final static int NOTEQUAL = 1; /** If the result document should be identical. */ public final static int IDENTICAL = 2; /** If the result document should not be identical. */ public final static int NOTIDENTICAL = 3; private Vector teststeps = new Vector(); /** * Create a new transformer test case. * * @param name Name of test case. */ public AbstractTransformerTestCase(String name) { super(name); } /** * Add a new test step to the test case. * * @param transformer Hint of the transformer. * @param objectmodel Object model. * @param source Source for the transformer. * @param parameters Transformer parameters. * @param input Input XML document, which go throught * the transformer. * @param assertion Assertion XML document. * @param assertiontype (EQUAL|NOTEQUAL|IDENTICAL|NOTIDENTICAL) */ public final void addTestStep(String transformer, Map objectmodel, String source, Parameters parameters, String input, String assertion, int assertiontype) { TestStep test = new TestStep(); test.transformer = transformer; test.objectmodel = objectmodel; test.source = source; test.parameters = parameters; test.input = input; test.assertion = assertion; test.assertiontype = assertiontype; teststeps.addElement(test); } /** * Test the transformers and his output */ public final void testTransformer() { try { ComponentSelector selector = null; Transformer transformer = null; SourceResolver resolver = null; SAXParser parser = null; Source inputsource = null; Source assertionsource = null; try { selector = (ComponentSelector) this.manager.lookup(Transformer.ROLE+ "Selector"); assertNotNull("Test lookup of transformer selector", selector); resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE); assertNotNull("Test lookup of source resolver", resolver); parser = (SAXParser) this.manager.lookup(SAXParser.ROLE); assertNotNull("Test lookup of parser", parser); TestStep test; int count = 0; for (Enumeration e = teststeps.elements(); e.hasMoreElements(); ) { test = (TestStep) e.nextElement(); count++; getLogger().info(count+".Test step"); assertNotNull("Test if transformer name is not null", test.transformer); transformer = (Transformer) selector.select(test.transformer); assertNotNull("Test lookup of transformer", transformer); DOMBuilder builder = new DOMBuilder(); if ((test.assertiontype==EQUAL) || (test.assertiontype==NOTEQUAL)) { transformer.setConsumer(new WhitespaceFilter(builder)); } else { transformer.setConsumer(builder); } transformer.setup(new SourceResolverAdapter(resolver, this.manager), test.objectmodel, test.source, test.parameters); assertNotNull("Test if input document is not null", test.input); inputsource = resolver.resolveURI(test.input); assertNotNull("Test lookup of input source", inputsource); assertNotNull("Test if inputstream of the input source is not null", inputsource.getInputStream()); parser.parse(new InputSource(inputsource.getInputStream()), (ContentHandler) transformer, (LexicalHandler) transformer); Document document = builder.getDocument(); assertNotNull("Test for transformer document", document); assertNotNull("Test if assertion document is not null", test.assertion); assertionsource = resolver.resolveURI(test.assertion); assertNotNull("Test lookup of assertion source", assertionsource); assertNotNull("Test if inputstream of the assertion source is not null", assertionsource.getInputStream()); builder = new DOMBuilder(); if ((test.assertiontype==EQUAL) || (test.assertiontype==NOTEQUAL)) { parser.parse(new InputSource(assertionsource.getInputStream()), (ContentHandler) new WhitespaceFilter(builder), (LexicalHandler) builder); } else { parser.parse(new InputSource(assertionsource.getInputStream()), (ContentHandler) builder, (LexicalHandler) builder); } Document assertiondocument = builder.getDocument(); assertNotNull("Test if assertion document exists", resolver); assertTrue("Test if assertion type is correct", (test.assertiontype>=EQUAL) && (test.assertiontype<=NOTIDENTICAL)); NodeList childs = assertiondocument.getDocumentElement().getChildNodes(); switch (test.assertiontype) { case EQUAL : document.getDocumentElement().normalize(); assertiondocument.getDocumentElement().normalize(); assertXMLEqual(compareXML(assertiondocument, document), true, "Test if the assertion document is equal"); break; case NOTEQUAL : document.getDocumentElement().normalize(); assertiondocument.getDocumentElement().normalize(); assertXMLEqual(compareXML(assertiondocument, document), false, "Test if the assertion document is not equal"); break; case IDENTICAL : assertXMLIdentical(compareXML(assertiondocument, document), true, "Test if the assertion document is identical"); break; case NOTIDENTICAL : assertXMLIdentical(compareXML(assertiondocument, document), false, "Test if the assertion document is not identical"); break; } selector.release(transformer); transformer = null; resolver.release(inputsource); inputsource = null; resolver.release(assertionsource); assertionsource = null; } } catch (ComponentException ce) { getLogger().error("Could not retrieve transformer", ce); ce.printStackTrace(); fail("Could not retrieve transformer:"+ce.toString()); } catch (SAXException saxe) { getLogger().error("Could not execute test", saxe); fail("Could not execute test:"+saxe.toString()); } catch (IOException ioe) { getLogger().error("Could not execute test", ioe); fail("Could not execute test:"+ioe.toString()); } catch (SourceException se) { getLogger().error("Could not retrieve sources", se); fail("Could not retrieve sources:"+se.toString()); } catch (ProcessingException pe) { getLogger().error("Could not execute test", pe); pe.printStackTrace(); fail("Could not execute test:"+pe.toString()); } finally { if (transformer!=null) selector.release(transformer); if (selector!=null) this.manager.release(selector); if (resolver!=null) this.manager.release(resolver); if (inputsource!=null) resolver.release(inputsource); if (inputsource!=null) resolver.release(assertionsource); if (resolver!=null) this.manager.release(resolver); if (parser!=null) this.manager.release((Component) parser); } } catch (Exception excep) { excep.printStackTrace(); } } /** * Compare two XML documents provided as strings * @param control Control document * @param test Document to test * @return Diff object describing differences in documents */ public final Diff compareXML(Document control, Document test) { return new Diff(control, test); } /** * Assert that the result of an XML comparison is or is not similar. * @param diff the result of an XML comparison * @param assertion true if asserting that result is similar */ public final void assertXMLEqual(Diff diff, boolean assertion) { XMLUnit.setIgnoreWhitespace(true); assertEquals(diff.toString(), assertion, diff.similar()); } /** * Assert that the result of an XML comparison is or is not similar. * @param diff the result of an XML comparison * @param assertion true if asserting that result is similar * @param msg additional message to display if assertion fails */ public final void assertXMLEqual(Diff diff, boolean assertion, String msg) { XMLUnit.setIgnoreWhitespace(true); assertEquals(msg+", "+diff.toString(), assertion, diff.similar()); } /** * Assert that the result of an XML comparison is or is not identical * @param diff the result of an XML comparison * @param assertion true if asserting that result is identical */ public final void assertXMLIdentical(Diff diff, boolean assertion) { XMLUnit.setIgnoreWhitespace(false); assertEquals(diff.toString(), assertion, diff.identical()); } /** * Assert that the result of an XML comparison is or is not identical * @param diff the result of an XML comparison * @param assertion true if asserting that result is identical * @param msg additional message to display if assertion fails */ public final void assertXMLIdentical(Diff diff, boolean assertion, String msg) { XMLUnit.setIgnoreWhitespace(false); assertEquals(msg+", "+diff.toString(), assertion, diff.identical()); } /** * Inner class for a test step. */ private class TestStep { /** Hint of the transformer. */ public String transformer = null; /** Object model. */ public Map objectmodel = null; /** Source for the transformer. */ public String source = null; /** Transformer parameters. */ public Parameters parameters = null; /** Input XML document, which go throught * the transformer. */ public String input = null; /** Assertion XML document. */ public String assertion = null; /** (EQUAL|NOTEQUAL|IDENTICAL|NOTIDENTICAL) */ public int assertiontype = EQUAL; } } 1.1 xml-cocoon2/src/test/org/apache/cocoon/xml/WhitespaceFilter.java Index: WhitespaceFilter.java =================================================================== /* ============================================================================ The Apache Software License, Version 1.1 ============================================================================ Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modifica- tion, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The end-user documentation included with the redistribution, if any, must include the following acknowledgment: "This product includes software developed by the Apache Software Foundation (http://www.apache.org/)." Alternately, this acknowledgment may appear in the software itself, if and wherever such third-party acknowledgments normally appear. 4. The names "Apache Cocoon" and "Apache Software Foundation" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact [EMAIL PROTECTED] 5. Products derived from this software may not be called "Apache", nor may "Apache" appear in their name, without prior written permission of the Apache Software Foundation. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the Apache Software Foundation and was originally created by Stefano Mazzocchi <[EMAIL PROTECTED]>. For more information on the Apache Software Foundation, please see <http://www.apache.org/>. */ package org.apache.cocoon.xml; import org.apache.cocoon.xml.AbstractXMLPipe; import org.xml.sax.ContentHandler; import org.xml.sax.SAXException; /** * A SAX filter to remove whitespace character, which disturb the * XML matching process. * * @author <a href="mailto:[EMAIL PROTECTED]">Stephan Michels</a> * @version CVS $Id: WhitespaceFilter.java,v 1.1 2003/01/27 20:07:15 stephan Exp $ */ public class WhitespaceFilter extends AbstractXMLPipe { /** * Create a new WhitespaceFilter. * * @param handler Content handler. */ public WhitespaceFilter(ContentHandler handler) { setContentHandler(handler); } /** * Receive notification of character data. * * @param c The characters from the XML document. * @param start The start position in the array. * @param len The number of characters to read from the array. * * @throws SAXException */ public void characters(char c[], int start, int len) throws SAXException { if (contentHandler==null) { return; } for (int i = start; i<start+len; i++) if ( !Character.isWhitespace(c[i])) { StringBuffer buffer = new StringBuffer(); for (int j = i; j<start+len; j++) if ((c[j]!='\n') && (c[j]!='\r')) { buffer.append(c[j]); } if (buffer.length()>0) { contentHandler.characters(buffer.toString().toCharArray(), 0, buffer.length()); } return; } // otherwise ignore characters } /** * Receive notification of ignorable whitespace in element content. * * @param c The characters from the XML document. * @param start The start position in the array. * @param len The number of characters to read from the array. * * @throws SAXException */ public void ignorableWhitespace(char c[], int start, int len) throws SAXException { // ignore } } 1.2 +279 -282 xml-cocoon2/tools/lib/excalibur-testcase-1.0.jar <<Binary file>> 1.1 xml-cocoon2/tools/lib/xmlunit0.8.jar <<Binary file>>
---------------------------------------------------------------------- In case of troubles, e-mail: [EMAIL PROTECTED] To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]