/*
* Copyright (C) 2004 Joe Walnes.
* Copyright (C) 2006, 2007 XStream Committers.
* All rights reserved.
*
* The software in this package is published under the terms of the BSD
* style license a copy of which has been included with this distribution in
* the LICENSE.txt file.
*
* Created on 07. May 2004 by Joe Walnes
*/
package com.thoughtworks.acceptance;
import com.thoughtworks.acceptance.objects.StandardObject;
import com.thoughtworks.acceptance.someobjects.WithNamedList;
import com.thoughtworks.xstream.converters.ConversionException;
import com.thoughtworks.xstream.core.AbstractReferenceMarshaller;
import java.util.ArrayList;
import java.util.List;
public abstract class AbstractDuplicateReferenceTest extends AbstractAcceptanceTest {
protected void setUp() throws Exception {
super.setUp();
xstream.alias("thing", Thing.class);
}
public void testReferencesAreWorking() {
Thing sameThing = new Thing("hello");
Thing anotherThing = new Thing("hello");
List list = new ArrayList();
list.add(sameThing);
list.add(sameThing);
list.add(anotherThing);
String xml = xstream.toXML(list);
List result = (List) xstream.fromXML(xml);
assertEquals(list, result);
}
public void testReferencesAreTheSameObjectWhenDeserialized() {
Thing sameThing = new Thing("hello");
Thing anotherThing = new Thing("hello");
List list = new ArrayList();
list.add(sameThing);
list.add(sameThing);
list.add(anotherThing);
String xml = xstream.toXML(list);
List result = (List) xstream.fromXML(xml);
Thing t0 = (Thing) result.get(0);
Thing t1 = (Thing) result.get(1);
Thing t2 = (Thing) result.get(2);
t0.field = "bye";
assertEquals("bye", t0.field);
assertEquals("bye", t1.field);
assertEquals("hello", t2.field);
}
public static class Thing extends StandardObject {
public String field;
public Thing() {
}
public Thing(String field) {
this.field = field;
}
}
public static class MultRef {
public Object s1 = new Object();
public Object s2 = s1;
}
public void testMultipleReferencesToObjectsWithNoChildren() {
MultRef in = new MultRef();
assertSame(in.s1, in.s2);
String xml = xstream.toXML(in);
MultRef out = (MultRef) xstream.fromXML(xml);
assertSame(out.s1, out.s2);
}
public void testReferencesNotUsedForImmutableValueTypes() {
MultRef in = new MultRef();
in.s1 = new Integer(4);
in.s2 = in.s1;
String xml = xstream.toXML(in);
MultRef out = (MultRef) xstream.fromXML(xml);
assertEquals(out.s1, out.s2);
assertNotSame(out.s1, out.s2);
}
public void testReferencesUsedForMutableValueTypes() {
MultRef in = new MultRef();
in.s1 = new StringBuffer("hi");
in.s2 = in.s1;
String xml = xstream.toXML(in);
MultRef out = (MultRef) xstream.fromXML(xml);
StringBuffer buffer = (StringBuffer) out.s2;
buffer.append("bye");
assertEquals("hibye", out.s1.toString());
assertSame(out.s1, out.s2);
}
public void testReferencesToImplicitCollectionIsNotPossible() {
xstream.alias("strings", WithNamedList.class);
xstream.addImplicitCollection(WithNamedList.class, "things");
WithNamedList[] wls = new WithNamedList[]{
new WithNamedList("foo"), new WithNamedList("bar")};
wls[0].things.add("Hello");
wls[0].things.add("Daniel");
wls[1].things = wls[0].things;
try {
xstream.toXML(wls);
fail("Thrown " + AbstractReferenceMarshaller.ReferencedImplicitElementException.class.getName() + " expected");
} catch (final AbstractReferenceMarshaller.ReferencedImplicitElementException e) {
// OK
}
}
public void testReferencesToElementsOfImplicitCollectionIsPossible() {
xstream.alias("strings", WithNamedList.class);
xstream.addImplicitCollection(WithNamedList.class, "things");
WithNamedList[] wls = new WithNamedList[]{
new WithNamedList("foo"), new WithNamedList("bar")};
wls[0].things.add("Hello");
wls[0].things.add("Daniel");
wls[1].things.add(wls[0]);
String xml = xstream.toXML(wls);
WithNamedList[] out = (WithNamedList[]) xstream.fromXML(xml);
assertSame(out[0], out[1].things.get(0));
}
public void testReferencesToElementsOfNthImplicitCollectionIsPossible() {
xstream.alias("strings", WithNamedList.class);
xstream.addImplicitCollection(WithNamedList.class, "things");
WithNamedList[] wls = new WithNamedList[]{
new WithNamedList("foo"), new WithNamedList("bar"), new WithNamedList("foobar")};
wls[1].things.add("Hello");
wls[1].things.add("Daniel");
wls[2].things.add(wls[1]);
String xml = xstream.toXML(wls);
WithNamedList[] out = (WithNamedList[]) xstream.fromXML(xml);
assertSame(out[1], out[2].things.get(0));
}
public void testThrowsForInvalidReference() {
String xml = "" //
+ "<list>\n"
+ " <thing>\n"
+ " <field>Hello</field>\n"
+ " </thing>\n"
+ " <thing reference=\"foo\">\n"
+ "</list>";
try {
xstream.fromXML(xml);
fail("Thrown " + ConversionException.class.getName() + " expected");
} catch (final ConversionException e) {
assertEquals("foo", e.get("reference"));
}
}
}