001/*
002 * Copyright (C) 2007 The Guava Authors
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package com.google.common.testing;
018
019import com.google.common.annotations.Beta;
020import com.google.common.annotations.GwtCompatible;
021import junit.framework.Assert;
022import junit.framework.AssertionFailedError;
023
024/**
025 * Tests serialization and deserialization of an object, optionally asserting that the resulting
026 * object is equal to the original.
027 *
028 * <p><b>GWT warning:</b> Under GWT, both methods simply returns their input, as proper GWT
029 * serialization tests require more setup. This no-op behavior allows test authors to intersperse
030 * {@code SerializableTester} calls with other, GWT-compatible tests.
031 *
032 *
033 * @author Mike Bostock
034 * @since 10.0
035 */
036@Beta
037@GwtCompatible // but no-op!
038public final class SerializableTester {
039  private SerializableTester() {}
040
041  /**
042   * Serializes and deserializes the specified object.
043   *
044   * <p><b>GWT warning:</b> Under GWT, this method simply returns its input, as proper GWT
045   * serialization tests require more setup. This no-op behavior allows test authors to intersperse
046   * {@code SerializableTester} calls with other, GWT-compatible tests.
047   *
048   * <p>Note that the specified object may not be known by the compiler to be a {@link
049   * java.io.Serializable} instance, and is thus declared an {@code Object}. For example, it might
050   * be declared as a {@code List}.
051   *
052   * @return the re-serialized object
053   * @throws RuntimeException if the specified object was not successfully serialized or
054   *     deserialized
055   */
056  @SuppressWarnings("unchecked")
057  public static <T> T reserialize(T object) {
058    return Platform.reserialize(object);
059  }
060
061  /**
062   * Serializes and deserializes the specified object and verifies that the re-serialized object is
063   * equal to the provided object, that the hashcodes are identical, and that the class of the
064   * re-serialized object is identical to that of the original.
065   *
066   * <p><b>GWT warning:</b> Under GWT, this method simply returns its input, as proper GWT
067   * serialization tests require more setup. This no-op behavior allows test authors to intersperse
068   * {@code SerializableTester} calls with other, GWT-compatible tests.
069   *
070   * <p>Note that the specified object may not be known by the compiler to be a {@link
071   * java.io.Serializable} instance, and is thus declared an {@code Object}. For example, it might
072   * be declared as a {@code List}.
073   *
074   * <p>Note also that serialization is not in general required to return an object that is
075   * {@linkplain Object#equals equal} to the original, nor is it required to return even an object
076   * of the same class. For example, if sublists of {@code MyList} instances were serializable,
077   * those sublists might implement a private {@code MySubList} type but serialize as a plain {@code
078   * MyList} to save space. So long as {@code MyList} has all the public supertypes of {@code
079   * MySubList}, this is safe. For these cases, for which {@code reserializeAndAssert} is too
080   * strict, use {@link #reserialize}.
081   *
082   * @return the re-serialized object
083   * @throws RuntimeException if the specified object was not successfully serialized or
084   *     deserialized
085   * @throws AssertionFailedError if the re-serialized object is not equal to the original object,
086   *     or if the hashcodes are different.
087   */
088  public static <T> T reserializeAndAssert(T object) {
089    T copy = reserialize(object);
090    new EqualsTester().addEqualityGroup(object, copy).testEquals();
091    Assert.assertEquals(object.getClass(), copy.getClass());
092    return copy;
093  }
094}