// CHECKSTYLE_OFF: Copyrighted to ASF
/*
 * Copyright 1999-2004 The Apache Software Foundation
 *
 * 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.
 */
// CHECKSTYLE_ON
package com.google.gwt.emultest.java.util;

/**
 * Tests base {@link java.lang.Object} methods and contracts.
 *
 * <p>To use, simply extend this class, and implement the {@link #makeObject()} method.
 *
 * <p>If your {@link Object} fails one of these tests by design, you may still use this base set of
 * cases. Simply override the test case (method) your {@link Object} fails.
 */
abstract class TestObject extends EmulTestBase {

  // current major release for Collections
  public static final int COLLECTIONS_MAJOR_VERSION = 2;

  /**
   * This constant makes it possible for TestMap (and other subclasses, if necessary) to
   * automatically check CVS for a versionX copy of a Serialized object, so we can make sure that
   * compatibility is maintained. See, for example, TestMap.getCanonicalFullMapName(Map map).
   * Subclasses can override this variable, indicating compatibility with earlier Collections
   * versions. Defaults to 1, the earliest Collections version. (Note: some collections did not even
   * exist in this version).
   *
   * @return 1
   */
  public int getCompatibilityVersion() {
    return 1;
  }

  /** Return a new, empty {@link Object} to used for testing. */
  public abstract Object makeObject();

  public void testObjectEqualsSelf() {
    Object obj = makeObject();
    assertEquals("A Object should equal itself", obj, obj);
  }

  public void testObjectHashCodeEqualsSelfHashCode() {
    Object obj = makeObject();
    assertEquals("hashCode should be repeatable", obj.hashCode(), obj.hashCode());
  }

  @SuppressWarnings("SelfEquals")
  public void testObjectHashCodeEqualsContract() {
    Object obj1 = makeObject();
    if (obj1.equals(obj1)) {
      assertEquals(
          "[1] When two objects are equal, their hashCodes should be also.",
          obj1.hashCode(),
          obj1.hashCode());
    }
    Object obj2 = makeObject();
    if (obj1.equals(obj2)) {
      assertEquals(
          "[2] When two objects are equal, their hashCodes should be also.",
          obj1.hashCode(),
          obj2.hashCode());
      assertTrue(
          "When obj1.equals(obj2) is true, then obj2.equals(obj1) should also be true",
          obj2.equals(obj1));
    }
  }

  public String getCanonicalEmptyCollectionName(Object object) {
    StringBuilder retval = new StringBuilder();
    retval.append("data/test/");
    String colName = object.getClass().getName();

    colName = colName.substring(colName.lastIndexOf(".") + 1);
    retval.append(colName);
    retval.append(".emptyCollection.version");
    retval.append(getCompatibilityVersion());
    retval.append(".obj");
    return retval.toString();
  }

  public String getCanonicalFullCollectionName(Object object) {
    StringBuilder retval = new StringBuilder();
    retval.append("data/test/");
    String colName = object.getClass().getName();
    colName = colName.substring(colName.lastIndexOf(".") + 1);
    retval.append(colName);
    retval.append(".fullCollection.version");
    retval.append(getCompatibilityVersion());
    retval.append(".obj");
    return retval.toString();
  }

  /**
   * Override this method if a subclass is testing a Collections that cannot serialize an "empty"
   * Collection (e.g. Comparators have no contents)
   *
   * @return true
   */
  public boolean supportsEmptyCollections() {
    return true;
  }

  /**
   * Override this method if a subclass is testing a Collections that cannot serialize a "full"
   * Collection (e.g. Comparators have no contents)
   *
   * @return true
   */
  public boolean supportsFullCollections() {
    return true;
  }
}
