View Javadoc
1   /*
2    * Redistribution and use of this software and associated documentation
3    * ("Software"), with or without modification, are permitted provided
4    * that the following conditions are met:
5    *
6    * 1. Redistributions of source code must retain copyright
7    *    statements and notices.  Redistributions must also contain a
8    *    copy of this document.
9    *
10   * 2. Redistributions in binary form must reproduce the
11   *    above copyright notice, this list of conditions and the
12   *    following disclaimer in the documentation and/or other
13   *    materials provided with the distribution.
14   *
15   * 3. The name "Exolab" must not be used to endorse or promote
16   *    products derived from this Software without prior written
17   *    permission of Intalio, Inc.  For written permission,
18   *    please contact info@exolab.org.
19   *
20   * 4. Products derived from this Software may not be called "Exolab"
21   *    nor may "Exolab" appear in their names without prior written
22   *    permission of Intalio, Inc. Exolab is a registered
23   *    trademark of Intalio, Inc.
24   *
25   * 5. Due credit should be given to the Exolab Project
26   *    (http://www.exolab.org/).
27   *
28   * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS
29   * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
30   * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
31   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
32   * INTALIO, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39   * OF THE POSSIBILITY OF SUCH DAMAGE.
40   *
41   * Copyright 2002-2003 (C) Intalio, Inc. All Rights Reserved.
42   *
43   * Portions of this file developed by Keith Visco after Jan 19 2005 are
44   * Copyright (C) 2005 Keith Visco. All Rights Reserverd.
45   *
46   * $Id: SchemaTestCase.java 6787 2007-01-29 06:00:49Z ekuns $
47   *
48   * Date         Author              Changes
49   * -----------------------------------------
50   * 01/23/2002   Keith Visco         Created
51   * 03/25/2002   Arnaud Blandin      Ported to CTF
52   * 10/15/2003   Arnaud Blandin      Improved reporting
53   */
54  package org.castor.xmlctf;
55  
56  import java.io.File;
57  import java.io.FileWriter;
58  import java.io.IOException;
59  import java.io.PrintWriter;
60  
61  import junit.framework.Test;
62  import junit.framework.TestSuite;
63  
64  import org.castor.xmlctf.util.CTFUtils;
65  import org.castor.xmlctf.util.FileServices;
66  import org.exolab.castor.tests.framework.testDescriptor.SchemaDifferences;
67  import org.exolab.castor.tests.framework.testDescriptor.UnitTestCase;
68  import org.exolab.castor.tests.framework.testDescriptor.types.FailureStepType;
69  import org.exolab.castor.xml.XMLContext;
70  import org.exolab.castor.xml.schema.Schema;
71  import org.exolab.castor.xml.schema.SchemaContextImpl;
72  import org.exolab.castor.xml.schema.reader.SchemaReader;
73  import org.exolab.castor.xml.schema.writer.SchemaWriter;
74  import org.xml.sax.InputSource;
75  
76  /**
77   * A JUnit test case for testing the Castor Schema Object Model.
78   *
79   * @author <a href="mailto:keith AT kvisco DOT com">Keith Visco</a>
80   * @author <a href="mailto:blandin@intalio.com">Arnaud Blandin</a>
81   * @version $Revision: 6787 $ $Date: 2006-04-26 15:14:53 -0600 (Wed, 26 Apr 2006) $
82   */
83  public class SchemaTestCase extends XMLTestCase {
84  
85      /** The name of the schema to test. */
86      private String         _schemaName;
87      /** The count of differences expected for the file-reference comparison. */
88      private final int      _differenceCountReference;
89      /** Gold file to compare a schema against.  Optional.  Only needed if
90       * schema changes during parsing, i.e., due to redefine element. */
91      protected final String _goldFileName;
92  
93      /**
94       * Default constructor
95       * @param name the name of the test
96       */
97      public SchemaTestCase(final String name) {
98          super(name);
99          throw new IllegalArgumentException("You cannot use the name-only constructor");
100     } //-- SchemaTest
101 
102     /**
103      * Creates a new SchemaTest with the given name
104      * @param castorTc the reference to the jar/directory
105      * @param tc the UnitTestCase that wraps the configuration for this XML Test case.
106      */
107     public SchemaTestCase(final CastorTestCase castorTc, final UnitTestCase tc) {
108         super(castorTc, tc);
109         _differenceCountReference = getSchemaDifferenceCount(tc, FailureStepType.COMPARE_TO_REFERENCE);
110         _goldFileName             = tc.getGoldFile();
111     } //-- SchemaTest
112 
113     /**
114      * Looks for and returns the difference count for the given step
115      * @param tc the UnitTestCase that wraps the configuration for this XML Test case.
116      * @param step the step to look for
117      * @return the difference count for the given step
118      */
119     private int getSchemaDifferenceCount(final UnitTestCase tc, final FailureStepType step) {
120         SchemaDifferences[] diff = tc.getSchemaDifferences();
121         for (int i = 0; i < diff.length; i++) {
122             if (diff[i].getFailureStep().equals(step)) {
123                 return diff[i].getContent();
124             }
125         }
126         return 0;
127     }
128 
129     /**
130      * Sets the name of the XML schema file to test.
131      *
132      * @param name the name of the XML schema file to test.
133      */
134     public void setSchemaName(final String name) {
135         _schemaName = name;
136     }
137 
138     public static Test suite() {
139         return new TestSuite();
140     } //-- suite
141 
142     protected void setUp() throws Exception {
143         verbose("\n================================================");
144         verbose("Test suite '"+_test.getName()+"': setting up test '" + _name+"'");
145         verbose("================================================\n");
146 
147         try {
148             FileServices.copySupportFiles(_test.getTestFile(), _outputRootFile);
149         } catch (IOException e) {
150             fail("IOException copying support files " + e);
151         }
152         if (getXMLContext() == null) {
153          // not wrapped inside a TestWithXy test!
154             setXMLContext(new XMLContext());
155         }
156     }
157 
158     /**
159      * Cleans up after this unit test (nothing to do except provide output).
160      * @throws java.lang.Exception never
161      */
162     protected void tearDown() throws Exception {
163         verbose("\n================================================");
164         verbose("Test suite '"+_test.getName()+"': test '" + _name+"' complete.");
165         verbose("================================================\n");
166     }
167 
168     /**
169      * Override this method to run the test and assert its state.
170      *
171      * @throws Throwable if any exception is thrown
172      */
173     public void runTest() throws Throwable {
174         if (_skip) {
175             verbose("-->Skipping the test");
176             return;
177         }
178 
179         File schemaFile = new File(_test.getTestFile() + "/" + _schemaName);
180         String schemaURL = schemaFile.toURL().toString();
181 
182         Schema schema = testReadingSchema(schemaURL);
183         if (schema == null) {
184             return;
185         }
186         testWritingSchema(schemaURL, schema);
187 
188         // Compare marshaled schema to gold file if provided, otherwise to input file
189         compareSchemaFiles(schemaFile);
190 
191         if (_failure != null && _failure.getContent()) {
192             fail("The schema test was expected to fail, but passed");
193         }
194     } //-- runTest
195 
196     private void compareSchemaFiles(final File schemaFile) throws IOException {
197         File file = new File(_outputRootFile, _schemaName.substring(0,_schemaName.lastIndexOf('.'))
198                               + "-output" + FileServices.XSD);
199 
200         String goldFileName = (_goldFileName != null) ? _outputRootFile + "/" +  _goldFileName
201                                                       : schemaFile.getAbsolutePath();
202 
203         int result = CTFUtils.compare(goldFileName, file.getAbsolutePath());
204         verbose("----> Compare marshaled schema to gold file '" + _goldFileName + "': " + ((result == 0)?"OK":"### Failed ### "));
205 
206         final FailureStepType step = _failure != null ? _failure.getFailureStep() : null;
207         final boolean expectedToFail= _failure != null && _failure.getContent()
208                                       && (step == null || step.equals(FailureStepType.COMPARE_TO_REFERENCE));
209 
210         if (_failure == null || !_failure.getContent()) {
211             assertEquals("The Marshaled schema differs from the gold file", _differenceCountReference, result);
212         } else if (expectedToFail) {
213             assertTrue("The Marshaled schema was expected to differ from the" +
214                        " gold file, but did not", result != _differenceCountReference);
215         }
216     }
217 
218     /**
219      * Reads and returns the provided XML schema.
220      *
221      * @param url the schema URL
222      * @return the Schema that was read in
223      */
224     private Schema testReadingSchema(final String url) {
225         verbose("--> Reading XML Schema: " + url);
226         try {
227             SchemaReader reader = new SchemaReader();
228             
229             reader.setSchemaContext(new SchemaContextImpl());
230             reader.setInputSource(new InputSource(url));
231             
232             Schema returnValue  = reader.read();
233             if (_failure != null && _failure.getContent() && _failure.getFailureStep() != null &&
234                  _failure.getFailureStep().equals(FailureStepType.PARSE_SCHEMA)) {
235                 fail("Reading/Parsing the schema was expected to fail, but succeeded");
236             }
237             return returnValue;
238         } catch (Exception e) {
239             if (!checkExceptionWasExpected(e, FailureStepType.PARSE_SCHEMA)) {
240                 fail("Unable to read Schema '" + url + "': " + e.toString());
241             }
242         }
243 
244         return null;
245     }
246 
247     /**
248      * Writes the provided schema to disk.
249      *
250      * @param url schema url, used only in diagnostic output
251      * @param schema the schema to write
252      */
253     private void testWritingSchema(final String url, final Schema schema) {
254         // First write the schema to disk
255         try {
256             String fileName = _schemaName.substring(0,_schemaName.lastIndexOf('.'))
257                               + "-output" + FileServices.XSD;
258             verbose("--> Writing XML Schema: " + fileName);
259 
260             File         output = new File(_outputRootFile, fileName);
261             FileWriter   writer = new FileWriter(output);
262             
263             SchemaWriter schemaWriter = new SchemaWriter();
264             schemaWriter.setSchemaContext(new SchemaContextImpl());
265             schemaWriter.setDocumentHandler(new PrintWriter(writer, true));
266             
267             schemaWriter.write(schema);
268             writer.close();
269         } catch (Exception e) {
270             if (!checkExceptionWasExpected(e, FailureStepType.WRITE_SCHEMA)) {
271                 fail("Failed to write Schema '" + url + "' to disk: " + e.toString());
272             }
273             return;
274         }
275 
276         if (_failure != null && _failure.getContent() && _failure.getFailureStep() != null &&
277             _failure.getFailureStep().equals(FailureStepType.WRITE_SCHEMA)) {
278             fail("Writing the schema was expected to fail, but succeeded");
279         }
280     }
281 
282 } //-- SchemaTest