/*
* Copyright 2006 Edward Kuns
*
* Licensed 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: TestWithRandomDocument.java 0000 2006-10-19 22:00:00Z ekuns $
*/
package org.castor.xmlctf;
import java.io.File;
import java.io.FileWriter;
import junit.framework.TestCase;
import org.exolab.castor.tests.framework.testDescriptor.FailureType;
import org.exolab.castor.tests.framework.testDescriptor.types.FailureStepType;
import org.exolab.castor.xml.XMLContext;
/**
* Implements a test case that tests code written by the XML source generator.
* This class uses the generated source to write a randomly generated XML
* element to a file.
* <p>
* The test follows this sequence:
* <ol>
* <li>Instantiates a random object model using the randomize function.</li>
* <li>Marshals it to a file.</li>
* <li>Unmarshals the created file.</li>
* <li>Check that the result object is equal to the start object.</li>
* </ol>
*
* @author <a href="mailto:gignoux@kernelcenter.org">Sebastien Gignoux</a>
* @author <a href="mailto:blandin@intalio.com">Arnaud Blandin</a>
* @author <a href="mailto:edward.kuns@aspect.com">Edward Kuns</a>
* @version $Revision: 0000 $ $Date: $
*/
class TestWithRandomObject extends TestCase {
/** We add this fixed string to the end of our testcase name. */
private static final String RANDOM = "_RandomObject";
/** We delegate all actions to this test case. */
private final XMLTestCase _delegate;
/** The failure object that is not null is the test intends to fail. */
protected final FailureType _failure;
/** File name of our marshaled output. */
protected final String _outputName;
/**
* Blank constructor for this test case. This contructor is not useful, since
* no delegate test case is provided
* @param name Name of our delegate test case
*/
TestWithRandomObject(String name) {
super(name+RANDOM);
throw new IllegalArgumentException("You cannot use the name-only constructor");
}
/**
* Constructs a test case that when invoked will delegate to the provided
* test case.
* @param name Name of our delegate test case
* @param tc
*/
TestWithRandomObject(String name, XMLTestCase tc) {
super(name+RANDOM);
_delegate = tc;
_failure = tc._failure;
_outputName = _delegate._name.replace(' ', '_') + "-testWithRandomObject";
}
/**
* Provides setup for our delegated test case, depending on the type of
* test case we are delegating for.
* @throws Exception if anything goes wrong during setup
*/
protected void setUp() throws Exception {
_delegate.setXMLContext(new XMLContext());
_delegate.setUp();
// if (_delegate instanceof MarshallingFrameworkTestCase) {
// ((MarshallingFrameworkTestCase)_delegate).setUp();
// } else if (_delegate instanceof SourceGeneratorTestCase) {
// ((SourceGeneratorTestCase)_delegate).setUp();
// }
}
/**
* Provides tear down for our delegated test case, depending on the type of
* test case we are delegating for.
* @throws Exception if anything goes wrong during teardown
*/
protected void tearDown() throws Exception {
_delegate.setUp();
// if (_delegate instanceof MarshallingFrameworkTestCase) {
// ((MarshallingFrameworkTestCase)_delegate).tearDown();
// } else if (_delegate instanceof SourceGeneratorTestCase) {
// ((SourceGeneratorTestCase)_delegate).tearDown();
// }
}
/**
* Runs our test case using our delegate object where necessary.
*/
public void runTest() throws Exception { // FIXME - temporarily throws Exception
verbose("\n------------------------------");
verbose("Test with randomly generated object");
verbose("------------------------------\n");
if (_delegate._skip) {
verbose("-->Skipping the test");
return;
}
// Randomize an object model instance
CastorTestable randomizedObject = getRandomizedReference();
// Dump the new random object to a file
if (_delegate._hasDump) {
verbose("----> Dump the object to '" + _outputName + "-ref.dump" +"'");
FileWriter writer = new FileWriter(new File(_delegate._outputRootFile, _outputName + "-ref.dump"));
writer.write(randomizedObject.dumpFields());
writer.close();
}
// Marshal our reference object to disk
File marshal_output = _delegate.testMarshal(randomizedObject, _outputName + ".xml");
if (marshal_output == null) {
return;
}
// Unmarshal from disk
Object unmarshaledRandomizedObject;
try {
unmarshaledRandomizedObject = _delegate.testUnmarshal(marshal_output);
} catch (Exception e) {
if (!_delegate.checkExceptionWasExpected(e, FailureStepType.SECOND_UNMARSHAL)) {
fail("Exception Unmarshaling from disk " + e);
}
return;
}
if (_failure != null && _failure.getContent() && _failure.getFailureStep() != null &&
_failure.getFailureStep().equals(FailureStepType.SECOND_UNMARSHAL)) {
fail("Unmarshaling the marshaled random document was expected to fail, but succeeded");
}
// Dump the unmarshaled object to a file
if (_delegate._hasDump) {
verbose("---->Dump the object to '" + _outputName + "-unmar.dump" +"'");
FileWriter writer = new FileWriter(new File(_delegate._outputRootFile, _outputName + "-unmar.dump"));
writer.write(((CastorTestable)unmarshaledRandomizedObject).dumpFields());
writer.close();
}
// Compare unmarshaled output file to our initial randomized instance
boolean result = unmarshaledRandomizedObject.equals(randomizedObject);
verbose("----> Compare unmarshaled document to reference object: " + ((result)?"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()) {
assertTrue("The initial randomized object and the one resulting of the" +
" marshal/unmarshal process are different", result);
} else if (expectedToFail) {
assertFalse("Comparing the random object to the marshal+unmarshaled one" +
" was expected to fail, but succeeded", result);
}
if (expectedToFail ^ result) {
return;
}
if (_failure != null && _failure.getContent()) {
fail("The test with random document was expected to fail, but passed");
}
}
/**
* Creates and returns a new instance of the root object set with random values.
* @return a new instance of the root object set with random values.
* @throws InstantiationException
* @throws IllegalAccessException
*/
private CastorTestable getRandomizedReference() throws InstantiationException, IllegalAccessException {
verbose("--> Randomize an object model for the root '" + _delegate._rootClassName + "'.");
CastorTestable randomizedObject = ((CastorTestable)_delegate._rootClass.newInstance());
assertNotNull("Randomized object model is null", randomizedObject);
randomizedObject.randomizeFields();
return randomizedObject;
}
private void verbose(String message) {
_delegate.verbose(message);
}
}