SPR-8453 - SpringOXM CastorMarshaller tests

This commit is contained in:
Arjen Poutsma 2011-06-15 11:04:02 +00:00
parent 0346fbc154
commit 3b1190121f
4 changed files with 406 additions and 18 deletions

View File

@ -66,17 +66,6 @@
</SOURCES>
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$IVY_CACHE$/org.apache.xerces/com.springsource.org.apache.xerces/2.8.1/com.springsource.org.apache.xerces-2.8.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$IVY_CACHE$/org.apache.xerces/com.springsource.org.apache.xerces/2.8.1/com.springsource.org.apache.xerces-sources-2.8.1.jar!/" />
</SOURCES>
</library>
</orderEntry>
<orderEntry type="module-library">
<library>
<CLASSES>

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,11 +16,22 @@
package org.springframework.oxm.castor;
import java.io.StringWriter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamResult;
import static org.easymock.EasyMock.*;
import static org.junit.Assert.assertTrue;
import org.custommonkey.xmlunit.NamespaceContext;
import org.custommonkey.xmlunit.SimpleNamespaceContext;
import org.custommonkey.xmlunit.XMLUnit;
import org.custommonkey.xmlunit.XpathEngine;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
@ -28,11 +39,68 @@ import org.springframework.core.io.ClassPathResource;
import org.springframework.oxm.AbstractMarshallerTests;
import org.springframework.oxm.Marshaller;
import static org.custommonkey.xmlunit.XMLAssert.*;
import static org.easymock.EasyMock.*;
/**
* Tests the {@link CastorMarshaller} class.
*
* @author Arjen Poutsma
* @author Jakub Narloch
*/
public class CastorMarshallerTests extends AbstractMarshallerTests {
/**
* Represents the expected result that doesn't contain the xml declaration.
*/
private static final String DOCUMENT_EXPECTED_STRING = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<tns:flights xmlns:tns=\"http://samples.springframework.org/flight\">" +
"<tns:flight><tns:number>42</tns:number></tns:flight></tns:flights>";
/**
* Represents the expected result that doesn't contain the xml namespaces.
*/
private static final String SUPPRESSED_NAMESPACE_EXPECTED_STRING =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?><flights><flight><number>42</number></flight></flights>";
/**
* Represents the expected result with modified root element name.
*/
private static final String ROOT_ELEMENT_EXPECTED_STRING = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<tns:canceledFlights xmlns:tns=\"http://samples.springframework.org/flight\">" +
"<tns:flight><tns:number>42</tns:number></tns:flight></tns:canceledFlights>";
/**
* Represents the expected result with 'xsi:type' attribute.
*/
private static final String XSI_EXPECTED_STRING = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<objects><castor-object xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
" xsi:type=\"java:org.springframework.oxm.castor.CastorObject\">" +
"<name>test</name><value>8</value></castor-object></objects>";
/**
* Represents the expected result with suppressed 'xsi:type' attribute.
*/
private static final String SUPPRESSED_XSI_EXPECTED_STRING = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<objects><castor-object><name>test</name><value>8</value></castor-object></objects>";
/**
* Represents the expected result with 'xsi:type' attribute for root element.
*/
private static final String ROOT_WITH_XSI_EXPECTED_STRING = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<objects xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
" xsi:type=\"java:java.util.Arrays$ArrayList\">" +
"<castor-object xsi:type=\"java:org.springframework.oxm.castor.CastorObject\">" +
"<name>test</name><value>8</value></castor-object></objects>";
/**
* Represents the expected result without 'xsi:type' attribute for root element.
*/
private static final String ROOT_WITHOUT_XSI_EXPECTED_STRING = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<objects><castor-object xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
" xsi:type=\"java:org.springframework.oxm.castor.CastorObject\">" +
"<name>test</name><value>8</value></castor-object></objects>";
@Override
protected Marshaller createMarshaller() throws Exception {
CastorMarshaller marshaller = new CastorMarshaller();
@ -77,8 +145,185 @@ public class CastorMarshallerTests extends AbstractMarshallerTests {
@Test
public void supports() throws Exception {
assertTrue("CastorMarshaller does not support Flights", marshaller.supports(Flights.class));
assertTrue("CastorMarshaller does not support Flight", marshaller.supports(Flight.class));
Assert.assertTrue("CastorMarshaller does not support Flights", marshaller.supports(Flights.class));
Assert.assertTrue("CastorMarshaller does not support Flight", marshaller.supports(Flight.class));
}
/**
* Tests the marshal result when the {@link CastorMarshaller#setSuppressNamespaces(boolean)} is set to
* <code>true</code>.
*
* @throws Exception if any error occurs during test
*/
@Test
public void testSuppressNamespacesTrue() throws Exception {
getCastorMarshaller().setSuppressNamespaces(true);
String result = marshalFlights();
assertXMLEqual("Marshaller wrote invalid result", SUPPRESSED_NAMESPACE_EXPECTED_STRING, result);
}
/**
* Tests the marshal result when the {@link CastorMarshaller#setSuppressNamespaces(boolean)} is set to
* <code>false</code>.
*
* @throws Exception if any error occurs during test
*/
@Test
public void testSuppressNamespacesFalse() throws Exception {
getCastorMarshaller().setSuppressNamespaces(false);
String result = marshalFlights();
assertXMLEqual("Marshaller wrote invalid result", EXPECTED_STRING, result);
}
@Test
@Ignore("Not working yet")
public void testSuppressXsiTypeTrue() throws Exception {
CastorObject castorObject = createCastorObject();
getCastorMarshaller().setSuppressXsiType(true);
getCastorMarshaller().setRootElement("objects");
String result = marshal(Arrays.asList(castorObject));
assertXMLEqual("Marshaller wrote invalid result", SUPPRESSED_XSI_EXPECTED_STRING, result);
}
@Test
@Ignore("Not working yet")
public void testSuppressXsiTypeFalse() throws Exception {
CastorObject castorObject = createCastorObject();
getCastorMarshaller().setSuppressXsiType(false);
getCastorMarshaller().setRootElement("objects");
String result = marshal(Arrays.asList(castorObject));
assertXMLEqual("Marshaller wrote invalid result", XSI_EXPECTED_STRING, result);
}
@Test
public void testMarshalAsDocumentTrue() throws Exception {
getCastorMarshaller().setMarshalAsDocument(true);
String result = marshalFlights();
assertXMLEqual("Marshaller wrote invalid result", DOCUMENT_EXPECTED_STRING, result);
Assert.assertTrue("Result doesn't contain xml declaration.",
result.contains("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"));
}
@Test
public void testMarshalAsDocumentFalse() throws Exception {
getCastorMarshaller().setMarshalAsDocument(true);
String result = marshalFlights();
assertXMLEqual("Marshaller wrote invalid result", EXPECTED_STRING, result);
Assert.assertFalse("Result contains xml declaration.", result.matches("<\\?\\s*xml"));
}
@Test
public void testRootElement() throws Exception {
getCastorMarshaller().setRootElement("canceledFlights");
String result = marshalFlights();
assertXMLEqual("Marshaller wrote invalid result", ROOT_ELEMENT_EXPECTED_STRING, result);
}
@Test
public void testNoNamespaceSchemaLocation() throws Exception {
String noNamespaceSchemaLocation = "flights.xsd";
getCastorMarshaller().setNoNamespaceSchemaLocation(noNamespaceSchemaLocation);
String result = marshalFlights();
assertXpathEvaluatesTo("The xsi:noNamespaceSchemaLocation hasn't been written or has invalid value.",
noNamespaceSchemaLocation, "/tns:flights/@xsi:noNamespaceSchemaLocation", result);
assertXMLEqual("Marshaller wrote invalid result", EXPECTED_STRING, result);
}
@Test
public void testSchemaLocation() throws Exception {
String schemaLocation = "flights.xsd";
getCastorMarshaller().setSchemaLocation(schemaLocation);
String result = marshalFlights();
assertXpathEvaluatesTo("The xsi:noNamespaceSchemaLocation hasn't been written or has invalid value.",
schemaLocation, "/tns:flights/@xsi:schemaLocation", result);
assertXMLEqual("Marshaller wrote invalid result", EXPECTED_STRING, result);
}
@Test
@Ignore("Not working yet")
public void testUseXsiTypeAsRootTrue() throws Exception {
CastorObject castorObject = createCastorObject();
getCastorMarshaller().setSuppressXsiType(false);
getCastorMarshaller().setUseXSITypeAtRoot(true);
getCastorMarshaller().setRootElement("objects");
String result = marshal(Arrays.asList(castorObject));
assertXMLEqual("Marshaller wrote invalid result", ROOT_WITH_XSI_EXPECTED_STRING, result);
}
@Test
@Ignore("Not working yet")
public void testUseXsiTypeAsRootFalse() throws Exception {
CastorObject castorObject = createCastorObject();
getCastorMarshaller().setSuppressXsiType(false);
getCastorMarshaller().setUseXSITypeAtRoot(false);
getCastorMarshaller().setRootElement("objects");
String result = marshal(Arrays.asList(castorObject));
assertXMLEqual("Marshaller wrote invalid result", ROOT_WITHOUT_XSI_EXPECTED_STRING, result);
}
private CastorMarshaller getCastorMarshaller() {
return (CastorMarshaller) marshaller;
}
private String marshal(Object object) throws Exception {
StringWriter writer = new StringWriter();
StreamResult result = new StreamResult(writer);
getCastorMarshaller().marshal(object, result);
return writer.toString();
}
private String marshalFlights() throws Exception {
return marshal(flights);
}
/**
* Asserts the values of xpath expression evaluation is exactly the same as expected value. </p> The xpath may contain
* the xml namespace prefixes, since namespaces from flight example are being registered.
*
* @param msg the error message that will be used in case of test failure
* @param expected the expected value
* @param xpath the xpath to evaluate
* @param xmlDoc the xml to use
* @throws Exception if any error occurs during xpath evaluation
*/
private void assertXpathEvaluatesTo(String msg, String expected, String xpath, String xmlDoc) throws Exception {
Map<String, String> namespaces = new HashMap<String, String>();
namespaces.put("tns", "http://samples.springframework.org/flight");
namespaces.put("xsi", "http://www.w3.org/2001/XMLSchema-instance");
NamespaceContext ctx = new SimpleNamespaceContext(namespaces);
XpathEngine engine = XMLUnit.newXpathEngine();
engine.setNamespaceContext(ctx);
Document doc = XMLUnit.buildControlDocument(xmlDoc);
NodeList node = engine.getMatchingNodes(xpath, doc);
assertEquals(msg, expected, node.item(0).getNodeValue());
}
/**
* Creates a instance of {@link CastorObject} for testing.
*
* @return a instance of {@link CastorObject}
*/
private CastorObject createCastorObject() {
CastorObject castorObject = new CastorObject();
castorObject.setName("test");
castorObject.setValue(8);
return castorObject;
}
}

View File

@ -0,0 +1,33 @@
/*
* Copyright 2002-2011 the original author or authors.
*
* 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.
*/
package org.springframework.oxm.castor;
/** @author Arjen Poutsma */
public class CastorObject {
private String name;
private int value;
public void setName(String name) {
this.name = name;
}
public void setValue(int value) {
this.value = value;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -21,18 +21,39 @@ import java.io.IOException;
import java.io.StringReader;
import javax.xml.transform.stream.StreamSource;
import static org.junit.Assert.*;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.core.io.ClassPathResource;
import org.springframework.oxm.AbstractUnmarshallerTests;
import org.springframework.oxm.MarshallingException;
import org.springframework.oxm.Unmarshaller;
import static org.junit.Assert.*;
/**
* Tests the {@link CastorMarshaller} class.
*
* @author Arjen Poutsma
* @author Jakub Narloch
*/
public class CastorUnmarshallerTests extends AbstractUnmarshallerTests {
/**
* Represents the xml with additional attribute that is not mapped in Castor config.
*/
protected static final String EXTRA_ATTRIBUTES_STRING =
"<tns:flights xmlns:tns=\"http://samples.springframework.org/flight\">" +
"<tns:flight status=\"canceled\"><tns:number>42</tns:number></tns:flight></tns:flights>";
/**
* Represents the xml with additional element that is not mapped in Castor config.
*/
protected static final String EXTRA_ELEMENTS_STRING =
"<tns:flights xmlns:tns=\"http://samples.springframework.org/flight\">" +
"<tns:flight><tns:number>42</tns:number><tns:date>2011-06-14</tns:date>" +
"</tns:flight></tns:flights>";
@Override
protected void testFlights(Object o) {
Flights flights = (Flights) o;
@ -89,5 +110,105 @@ public class CastorUnmarshallerTests extends AbstractUnmarshallerTests {
assertEquals("Invalid items", 20, (int)item.getQuantity());
}
@Test
public void testWhitespacePreserveTrue() throws Exception {
getCastorUnmarshaller().setWhitespacePreserve(true);
Object result = unmarshalFlights();
testFlights(result);
}
@Test
public void testWhitespacePreserveFalse() throws Exception {
getCastorUnmarshaller().setWhitespacePreserve(false);
Object result = unmarshalFlights();
testFlights(result);
}
@Test
public void testIgnoreExtraAttributesTrue() throws Exception {
getCastorUnmarshaller().setIgnoreExtraAttributes(true);
Object result = unmarshal(EXTRA_ATTRIBUTES_STRING);
testFlights(result);
}
@Test(expected = MarshallingException.class)
public void testIgnoreExtraAttributesFalse() throws Exception {
getCastorUnmarshaller().setIgnoreExtraAttributes(false);
unmarshal(EXTRA_ATTRIBUTES_STRING);
}
@Test
@Ignore("Not working yet")
public void testIgnoreExtraElementsTrue() throws Exception {
getCastorUnmarshaller().setIgnoreExtraElements(true);
getCastorUnmarshaller().setValidating(false);
Object result = unmarshal(EXTRA_ELEMENTS_STRING);
testFlights(result);
}
@Test(expected = MarshallingException.class)
public void testIgnoreExtraElementsFalse() throws Exception {
getCastorUnmarshaller().setIgnoreExtraElements(false);
unmarshal(EXTRA_ELEMENTS_STRING);
}
@Test
public void testObject() throws Exception {
Flights flights = new Flights();
getCastorUnmarshaller().setObject(flights);
Object result = unmarshalFlights();
testFlights(result);
assertSame("Result Flights is different object.", flights, result);
}
@Test
public void testClearCollectionsTrue() throws Exception {
Flights flights = new Flights();
flights.setFlight(new Flight[]{new Flight()});
getCastorUnmarshaller().setObject(flights);
getCastorUnmarshaller().setClearCollections(true);
Object result = unmarshalFlights();
assertSame("Result Flights is different object.", flights, result);
assertEquals("Result Flights has incorrect number of Flight.", 1, ((Flights) result).getFlightCount());
testFlights(result);
}
@Test
public void testClearCollectionsFalse() throws Exception {
Flights flights = new Flights();
flights.setFlight(new Flight[]{new Flight(), null});
getCastorUnmarshaller().setObject(flights);
getCastorUnmarshaller().setClearCollections(false);
Object result = unmarshalFlights();
assertSame("Result Flights is different object.", flights, result);
assertEquals("Result Flights has incorrect number of Flight.", 3, ((Flights) result).getFlightCount());
assertNull("Flight shouldn't have number.", flights.getFlight(0).getNumber());
assertNull("Null Flight was expected.", flights.getFlight()[1]);
testFlight(flights.getFlight()[2]);
}
private CastorMarshaller getCastorUnmarshaller() {
return (CastorMarshaller) unmarshaller;
}
private Object unmarshalFlights() throws Exception {
return unmarshal(INPUT_STRING);
}
private Object unmarshal(String xml) throws Exception {
StreamSource source = new StreamSource(new StringReader(xml));
return unmarshaller.unmarshal(source);
}
}