/* * Redistribution and use of this software and associated documentation * ("Software"), with or without modification, are permitted provided * that the following conditions are met: * * 1. Redistributions of source code must retain copyright * statements and notices. Redistributions must also contain a * copy of this document. * * 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 name "Exolab" must not be used to endorse or promote * products derived from this Software without prior written * permission of Intalio, Inc. For written permission, * please contact info@exolab.org. * * 4. Products derived from this Software may not be called "Exolab" * nor may "Exolab" appear in their names without prior written * permission of Intalio, Inc. Exolab is a registered * trademark of Intalio, Inc. * * 5. Due credit should be given to the Exolab Project * (http://www.exolab.org/). * * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS * ``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 * INTALIO, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, 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. * * Copyright 2002-2003 (C) Intalio, Inc. All Rights Reserved. * * Portions of this file developed by Keith Visco after Jan 19 2005 are * Copyright (C) 2005 Keith Visco. All Rights Reserverd. * * $Id: SchemaTestCase.java 6787 2007-01-29 06:00:49Z ekuns $ * * Date Author Changes * ----------------------------------------- * 01/23/2002 Keith Visco Created * 03/25/2002 Arnaud Blandin Ported to CTF * 10/15/2003 Arnaud Blandin Improved reporting */ package org.castor.xmlctf; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import junit.framework.Test; import junit.framework.TestSuite; import org.castor.xmlctf.util.CTFUtils; import org.castor.xmlctf.util.FileServices; import org.exolab.castor.tests.framework.testDescriptor.SchemaDifferences; import org.exolab.castor.tests.framework.testDescriptor.UnitTestCase; import org.exolab.castor.tests.framework.testDescriptor.types.FailureStepType; import org.exolab.castor.xml.XMLContext; import org.exolab.castor.xml.schema.Schema; import org.exolab.castor.xml.schema.SchemaContextImpl; import org.exolab.castor.xml.schema.reader.SchemaReader; import org.exolab.castor.xml.schema.writer.SchemaWriter; import org.xml.sax.InputSource; /** * A JUnit test case for testing the Castor Schema Object Model. * * @author <a href="mailto:keith AT kvisco DOT com">Keith Visco</a> * @author <a href="mailto:blandin@intalio.com">Arnaud Blandin</a> * @version $Revision: 6787 $ $Date: 2006-04-26 15:14:53 -0600 (Wed, 26 Apr 2006) $ */ public class SchemaTestCase extends XMLTestCase { /** The name of the schema to test. */ private String _schemaName; /** The count of differences expected for the file-reference comparison. */ private final int _differenceCountReference; /** Gold file to compare a schema against. Optional. Only needed if * schema changes during parsing, i.e., due to redefine element. */ protected final String _goldFileName; /** * Default constructor * @param name the name of the test */ public SchemaTestCase(final String name) { super(name); throw new IllegalArgumentException("You cannot use the name-only constructor"); } //-- SchemaTest /** * Creates a new SchemaTest with the given name * @param castorTc the reference to the jar/directory * @param tc the UnitTestCase that wraps the configuration for this XML Test case. */ public SchemaTestCase(final CastorTestCase castorTc, final UnitTestCase tc) { super(castorTc, tc); _differenceCountReference = getSchemaDifferenceCount(tc, FailureStepType.COMPARE_TO_REFERENCE); _goldFileName = tc.getGoldFile(); } //-- SchemaTest /** * Looks for and returns the difference count for the given step * @param tc the UnitTestCase that wraps the configuration for this XML Test case. * @param step the step to look for * @return the difference count for the given step */ private int getSchemaDifferenceCount(final UnitTestCase tc, final FailureStepType step) { SchemaDifferences[] diff = tc.getSchemaDifferences(); for (int i = 0; i < diff.length; i++) { if (diff[i].getFailureStep().equals(step)) { return diff[i].getContent(); } } return 0; } /** * Sets the name of the XML schema file to test. * * @param name the name of the XML schema file to test. */ public void setSchemaName(final String name) { _schemaName = name; } public static Test suite() { return new TestSuite(); } //-- suite protected void setUp() throws Exception { verbose("\n================================================"); verbose("Test suite '"+_test.getName()+"': setting up test '" + _name+"'"); verbose("================================================\n"); try { FileServices.copySupportFiles(_test.getTestFile(), _outputRootFile); } catch (IOException e) { fail("IOException copying support files " + e); } if (getXMLContext() == null) { // not wrapped inside a TestWithXy test! setXMLContext(new XMLContext()); } } /** * Cleans up after this unit test (nothing to do except provide output). * @throws java.lang.Exception never */ protected void tearDown() throws Exception { verbose("\n================================================"); verbose("Test suite '"+_test.getName()+"': test '" + _name+"' complete."); verbose("================================================\n"); } /** * Override this method to run the test and assert its state. * * @throws Throwable if any exception is thrown */ public void runTest() throws Throwable { if (_skip) { verbose("-->Skipping the test"); return; } File schemaFile = new File(_test.getTestFile() + "/" + _schemaName); String schemaURL = schemaFile.toURL().toString(); Schema schema = testReadingSchema(schemaURL); if (schema == null) { return; } testWritingSchema(schemaURL, schema); // Compare marshaled schema to gold file if provided, otherwise to input file compareSchemaFiles(schemaFile); if (_failure != null && _failure.getContent()) { fail("The schema test was expected to fail, but passed"); } } //-- runTest private void compareSchemaFiles(final File schemaFile) throws IOException { File file = new File(_outputRootFile, _schemaName.substring(0,_schemaName.lastIndexOf('.')) + "-output" + FileServices.XSD); String goldFileName = (_goldFileName != null) ? _outputRootFile + "/" + _goldFileName : schemaFile.getAbsolutePath(); int result = CTFUtils.compare(goldFileName, file.getAbsolutePath()); verbose("----> Compare marshaled schema to gold file '" + _goldFileName + "': " + ((result == 0)?"OK":"### Failed ### ")); final FailureStepType step = _failure != null ? _failure.getFailureStep() : null; final boolean expectedToFail= _failure != null && _failure.getContent() && (step == null || step.equals(FailureStepType.COMPARE_TO_REFERENCE)); if (_failure == null || !_failure.getContent()) { assertEquals("The Marshaled schema differs from the gold file", _differenceCountReference, result); } else if (expectedToFail) { assertTrue("The Marshaled schema was expected to differ from the" + " gold file, but did not", result != _differenceCountReference); } } /** * Reads and returns the provided XML schema. * * @param url the schema URL * @return the Schema that was read in */ private Schema testReadingSchema(final String url) { verbose("--> Reading XML Schema: " + url); try { SchemaReader reader = new SchemaReader(); reader.setSchemaContext(new SchemaContextImpl()); reader.setInputSource(new InputSource(url)); Schema returnValue = reader.read(); if (_failure != null && _failure.getContent() && _failure.getFailureStep() != null && _failure.getFailureStep().equals(FailureStepType.PARSE_SCHEMA)) { fail("Reading/Parsing the schema was expected to fail, but succeeded"); } return returnValue; } catch (Exception e) { if (!checkExceptionWasExpected(e, FailureStepType.PARSE_SCHEMA)) { fail("Unable to read Schema '" + url + "': " + e.toString()); } } return null; } /** * Writes the provided schema to disk. * * @param url schema url, used only in diagnostic output * @param schema the schema to write */ private void testWritingSchema(final String url, final Schema schema) { // First write the schema to disk try { String fileName = _schemaName.substring(0,_schemaName.lastIndexOf('.')) + "-output" + FileServices.XSD; verbose("--> Writing XML Schema: " + fileName); File output = new File(_outputRootFile, fileName); FileWriter writer = new FileWriter(output); SchemaWriter schemaWriter = new SchemaWriter(); schemaWriter.setSchemaContext(new SchemaContextImpl()); schemaWriter.setDocumentHandler(new PrintWriter(writer, true)); schemaWriter.write(schema); writer.close(); } catch (Exception e) { if (!checkExceptionWasExpected(e, FailureStepType.WRITE_SCHEMA)) { fail("Failed to write Schema '" + url + "' to disk: " + e.toString()); } return; } if (_failure != null && _failure.getContent() && _failure.getFailureStep() != null && _failure.getFailureStep().equals(FailureStepType.WRITE_SCHEMA)) { fail("Writing the schema was expected to fail, but succeeded"); } } } //-- SchemaTest