/* * Copyright (C) 2004, 2005 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 29. May 2004 by Joe Walnes */ package com.thoughtworks.xstream.converters.extended; import com.thoughtworks.acceptance.AbstractAcceptanceTest; import com.thoughtworks.xstream.XStream; import java.math.BigDecimal; /** * @author <a href="mailto:boxley@thoughtworks.com">B. K. Oxley (binkley)</a> */ public class ThrowableConverterTest extends AbstractAcceptanceTest { public void testDeserializesThrowable() { Throwable expected = new Throwable(); Throwable result = (Throwable) xstream.fromXML(xstream.toXML(expected)); assertThrowableEquals(expected, result); } public void testDeserializesException() { Exception expected = new Exception(); Throwable result = (Throwable) xstream.fromXML(xstream.toXML(expected)); assertThrowableEquals(expected, result); } public void testIncludesMessage() { Throwable expected = new Throwable("A MESSAGE"); Throwable result = (Throwable) xstream.fromXML(xstream.toXML(expected)); assertThrowableEquals(expected, result); } public void testIncludesCause() { Throwable expected = new Throwable(new Throwable()); Throwable result = (Throwable) xstream.fromXML(xstream.toXML(expected)); assertThrowableEquals(expected, result); } public void testIncludesCauseAndMessage() { Throwable expected = new Throwable("MESSAGE", new Throwable("CAUSE MESSAGE")); Throwable result = (Throwable) xstream.fromXML(xstream.toXML(expected)); assertThrowableEquals(expected, result); } public void testIncludesStackTrace() { try { throw new Exception(); } catch (Exception exception) { Throwable result = (Throwable) xstream.fromXML(xstream.toXML(exception)); assertThrowableEquals(exception, result); } } public static class MyException extends Exception { private BigDecimal number; public MyException(String msg, BigDecimal number) { super(msg); this.number = number; } public boolean equals(Object o) { return super.equals(o) && o instanceof MyException && number.equals(((MyException)o).number); } } public void testSerializesExtraFields() { try { throw new MyException("A MESSAGE", new BigDecimal(123.4)); } catch (MyException exception) { Throwable result = (Throwable) xstream.fromXML(xstream.toXML(exception)); assertThrowableEquals(exception, result); } } public void testSerializesWithNoSelfReferenceForUninitializedCauseInJdk14() { xstream.setMode(XStream.NO_REFERENCES); try { throw new RuntimeException("Without cause"); } catch (RuntimeException exception) { Throwable result = (Throwable) xstream.fromXML(xstream.toXML(exception)); assertThrowableEquals(exception, result); assertNull(exception.getCause()); assertNull(result.getCause()); } } public void testSerializesWithInitializedCauseInJdk14() { xstream.setMode(XStream.NO_REFERENCES); try { throw new RuntimeException("Without cause", null); } catch (RuntimeException exception) { Throwable result = (Throwable) xstream.fromXML(xstream.toXML(exception)); assertThrowableEquals(exception, result); assertNull(exception.getCause()); assertNull(result.getCause()); } } private static void assertThrowableEquals(final Throwable a, final Throwable b) { assertBoth(a, b, new MoreAssertions() { public void assertMoreSafely(final Object a, final Object b) { final Throwable ta = (Throwable) a, tb = (Throwable) b; assertEquals(ta.getClass(), tb.getClass()); assertEquals(ta.getMessage(), tb.getMessage()); assertThrowableEquals(ta.getCause(), tb.getCause()); assertArrayEquals(ta.getStackTrace(), tb.getStackTrace()); } }); } private static void assertArrayEquals(final Object[] expected, final Object[] actual) { StringBuffer expectedJoined = new StringBuffer(); StringBuffer actualJoined = new StringBuffer(); for (int i = 0; i < expected.length; i++) { expectedJoined.append(expected[i]).append('\n'); } for (int i = 0; i < actual.length; i++) { // JRockit adds ":???" for invalid line number actualJoined.append(actual[i].toString().replaceFirst(":\\?\\?\\?", "")).append('\n'); } assertEquals(expectedJoined.toString(), actualJoined.toString()); } private static void assertBoth(Object a, Object b, MoreAssertions moreAssertions) { if (null == a) { if (null == b) { return; } else { fail("Expected null, but was <" + b + ">"); } } else if (null == b) { fail("Expected <" + a + "> but was null"); } else { moreAssertions.assertMoreSafely(a, b); } } private interface MoreAssertions { void assertMoreSafely(final Object a, final Object b); } }