/*******************************************************************************
*
* Copyright (c) 2004-2010, Oracle Corporation.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*
*
*
*
*******************************************************************************/
package hudson.util;
import com.google.common.collect.ImmutableMap;
import hudson.model.Result;
import hudson.model.Run;
import java.util.Map;
import junit.framework.TestCase;
/**
* Tests for XML serialization of java objects.
* @author Kohsuke Kawaguchi, Mike Dillon, Alan Harder
*/
public class XStream2Test extends TestCase {
public static final class Foo {
Result r1,r2;
}
public void testMarshalValue() {
Foo f = new Foo();
f.r1 = f.r2 = Result.FAILURE;
String xml = Run.XSTREAM.toXML(f);
// we should find two "FAILURE"s as they should be written out twice
assertEquals(xml, 3, xml.split("FAILURE").length);
}
private static class Bar {
String s;
}
public static final class __Foo_Bar$Class {
String under_1 = "1", under__2 = "2",
_leadUnder1 = "L1", __leadUnder2 = "L2",
$dollar = "D1", dollar$2 = "D2";
}
/**
* Test marshal/unmarshal round trip for class/field names with _ and $ characters.
* (HUDSON-5768)
*/
public void testXmlRoundTrip() {
XStream2 xs = new XStream2();
__Foo_Bar$Class b = new __Foo_Bar$Class();
String xml = xs.toXML(b);
__Foo_Bar$Class b2 = (__Foo_Bar$Class)xs.fromXML(xml);
assertEquals(xml, b.under_1, b2.under_1);
assertEquals(xml, b.under__2, b2.under__2);
assertEquals(xml, b._leadUnder1, b2._leadUnder1);
assertEquals(xml, b.__leadUnder2, b2.__leadUnder2);
assertEquals(xml, b.$dollar, b2.$dollar);
assertEquals(xml, b.dollar$2, b2.dollar$2);
}
private static class Baz {
private Exception myFailure;
}
/**
* Verify RobustReflectionConverter can handle missing fields in a class extending
* Throwable/Exception (default ThrowableConverter registered by XStream calls
* ReflectionConverter directly, rather than our RobustReflectionConverter replacement).
* (HUDSON-5769)
*/
public void testUnmarshalThrowableMissingField() {
Baz baz = new Baz();
baz.myFailure = new Exception("foo");
XStream2 xs = new XStream2();
String xml = xs.toXML(baz);
baz = (Baz)xs.fromXML(xml);
assertEquals("foo", baz.myFailure.getMessage());
baz = (Baz)xs.fromXML("<hudson.util.XStream2Test_-Baz><myFailure>"
+ "<missingField>true</missingField>"
+ "<detailMessage>hoho</detailMessage>"
+ "<stackTrace><trace>"
+ "hudson.util.XStream2Test.testUnmarshalThrowableMissingField(XStream2Test.java:97)"
+ "</trace></stackTrace>"
+ "</myFailure></hudson.util.XStream2Test_-Baz>");
// Object should load, despite "missingField" in XML above
assertEquals("hoho", baz.myFailure.getMessage());
}
private static class ImmutableMapHolder {
ImmutableMap m;
}
private static class MapHolder {
Map m;
}
public void testImmutableMap() {
XStream2 xs = new XStream2();
roundtripImmutableMap(xs, ImmutableMap.of());
roundtripImmutableMap(xs, ImmutableMap.of("abc", "xyz"));
roundtripImmutableMap(xs, ImmutableMap.of("abc", "xyz", "def","ghi"));
roundtripImmutableMapAsPlainMap(xs, ImmutableMap.of());
roundtripImmutableMapAsPlainMap(xs, ImmutableMap.of("abc", "xyz"));
roundtripImmutableMapAsPlainMap(xs, ImmutableMap.of("abc", "xyz", "def","ghi"));
}
/**
* Since the field type is {@link ImmutableMap}, XML shouldn't contain a reference to the type name.
*/
private void roundtripImmutableMap(XStream2 xs, ImmutableMap<?,?> m) {
ImmutableMapHolder a = new ImmutableMapHolder();
a.m = m;
String xml = xs.toXML(a);
System.out.println(xml);
assertFalse("shouldn't contain the class name",xml.contains("google"));
assertFalse("shouldn't contain the class name",xml.contains("class"));
a = (ImmutableMapHolder)xs.fromXML(xml);
assertSame(m.getClass(),a.m.getClass()); // should get back the exact same type, not just a random map
assertEquals(m,a.m);
}
private void roundtripImmutableMapAsPlainMap(XStream2 xs, ImmutableMap<?,?> m) {
MapHolder a = new MapHolder();
a.m = m;
String xml = xs.toXML(a);
System.out.println(xml);
assertTrue("XML should mention the class name",xml.contains('\"'+ImmutableMap.class.getName()+'\"'));
a = (MapHolder)xs.fromXML(xml);
assertSame(m.getClass(),a.m.getClass()); // should get back the exact same type, not just a random map
assertEquals(m,a.m);
}
// @Bug(8006) -- Previously a null entry in an array caused NPE
public void testEmptyStack() {
assertEquals("<object-array><null/><null/></object-array>",
Run.XSTREAM.toXML(new Object[2]).replaceAll("[ \n\r\t]+", ""));
}
}