/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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
<<<<<<< Updated upstream
 *
 *     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
=======
 * 
 *     https://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 
>>>>>>> Stashed changes
 * limitations under the License.
 */

/*
 * StringIdentityTest.java
 *
 */

package javax.jdo.identity;

import javax.jdo.JDONullIdentityException;
import javax.jdo.util.BatchTestRunner;

/** */
public class StringIdentityTest extends SingleFieldIdentityTest {

  /** Creates a new instance of StringIdentityTest */
  public StringIdentityTest() {}

  /**
   * @param args the command line arguments
   */
  public static void main(String[] args) {
    BatchTestRunner.run(StringIdentityTest.class);
  }

  public void testConstructor() {
    StringIdentity c1 = new StringIdentity(Object.class, "1");
    StringIdentity c2 = new StringIdentity(Object.class, "1");
    StringIdentity c3 = new StringIdentity(Object.class, "2");
    assertEquals("Equal StringIdentity instances compare not equal.", c1, c2);
    assertFalse("Not equal StringIdentity instances compare equal", c1.equals(c3));
  }

  public void testToStringConstructor() {
    StringIdentity c1 = new StringIdentity(Object.class, "Now who's talking!");
    StringIdentity c2 = new StringIdentity(Object.class, c1.toString());
    assertEquals("Equal StringIdentity instances compare not equal.", c1, c2);
  }

  public void testSerialized() {
    StringIdentity c1 = new StringIdentity(Object.class, "1");
    StringIdentity c2 = new StringIdentity(Object.class, "1");
    StringIdentity c3 = new StringIdentity(Object.class, "2");
    Object[] scis = writeReadSerialized(new Object[] {c1, c2, c3});
    Object sc1 = scis[0];
    Object sc2 = scis[1];
    Object sc3 = scis[2];
    assertEquals("Equal StringIdentity instances compare not equal.", c1, sc1);
    assertEquals("Equal StringIdentity instances compare not equal.", c2, sc2);
    assertEquals("Equal StringIdentity instances compare not equal.", sc1, c2);
    assertEquals("Equal StringIdentity instances compare not equal.", sc2, c1);
    assertFalse("Not equal StringIdentity instances compare equal.", c1.equals(sc3));
    assertFalse("Not equal StringIdentity instances compare equal.", sc1.equals(c3));
    assertFalse("Not equal StringIdentity instances compare equal.", sc1.equals(sc3));
    assertFalse("Not equal StringIdentity instances compare equal.", sc3.equals(sc1));
  }

  public void testGetKeyAsObject() {
    StringIdentity c1 = new StringIdentity(Object.class, "1");
    assertEquals("keyAsObject doesn't match.", c1.getKeyAsObject(), "1");
  }

  public void testBadConstructorNullParam() {
    try {
      new StringIdentity(Object.class, null);
    } catch (JDONullIdentityException ex) {
      return;
    }
    fail("Failed to catch expected exception.");
  }

  public void testCompareTo() {
    StringIdentity c1 = new StringIdentity(Object.class, "1");
    StringIdentity c2 = new StringIdentity(Object.class, "1");
    StringIdentity c3 = new StringIdentity(Object.class, "2");
    StringIdentity c4 = new StringIdentity(Class.class, "1");
    assertEquals("Equal StringIdentity instances compare not equal.", 0, c1.compareTo(c2));
    assertTrue(
        "Not equal StringIdentity instances have wrong compareTo result", c1.compareTo(c3) < 0);
    assertTrue(
        "Not equal StringIdentity instances have wrong compareTo result", c3.compareTo(c1) > 0);
    assertTrue(
        "Not equal StringIdentity instances have wrong compareTo result", c1.compareTo(c4) > 0);
  }
}
