/*
 * QuadTest class.
 *
 * Copyright (C) 2007 SATOH Takayuki All Rights Reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
package ts.util;

import ts.tester.function.coverage.FunctionTester;
import ts.tester.function.print.*;
import ts.tester.util.ObjectSerializer;

/**
 * <code>Quad</code>クラスの機能試験クラス。
 *
 * @author  佐藤隆之. 
 * @version $Revision: 1.1.1.1 $, $Date: 2010-10-16 00:03:44 $
 */
public class QuadTest extends FunctionTester
{
  public static void main(String[] args)
  {
    try {
      PrinterGroup group = new PrinterGroup();
      group.addPrinter(new ConsolePrinter());
      group.addPrinter(new HtmlPrinter("SATOH Takayuki"));
      setPrinter(group);

      run(QuadTest.class, (args.length == 0) ? null : args[0]);
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }

  @Override
  protected void preTesting()
  {
    MSG("Quadクラスの機能試験を実行する。");
  }

  /* -- test case -- */

  public void constructor()
  {
    MSG("デフォルトコンストラクタの確認。");

    Quad<Object,Object,Object,Object> qua;
    qua = new Quad<Object,Object,Object,Object>();
    NULL(qua.getFirst ());
    NULL(qua.getSecond());
    NULL(qua.getThird ());
  }

  public void constructor_1st_2nd_3rd_4th()
  {
    MSG("4つのオブジェクトを引数にとるコンストラクタの確認。");

    Object o1 = new Object();
    Object o2 = new Object();
    Object o3 = new Object();
    Object o4 = new Object();
    Quad<Object,Object,Object,Object> qua;
    qua = new Quad<Object,Object,Object,Object>(o1, o2, o3, o4);
    EQUAL(qua.getFirst (), o1);
    EQUAL(qua.getSecond(), o2);
    EQUAL(qua.getThird (), o3);
    EQUAL(qua.getFourth(), o4);

    Quad<Object,Object,Object,Object> qua1;
    qua1 = new Quad<Object,Object,Object,Object>(
      new Integer(123), new Boolean(true), new Double(0.1234), "あいうえお");
    EQUAL(qua1.getFirst (), new Integer(123));
    EQUAL(qua1.getSecond(), Boolean.TRUE);
    EQUAL(qua1.getThird (), new Double(0.1234));
    EQUAL(qua1.getFourth(), "あいうえお");

    Quad<Object,Object,Object,Object> qua2;
    qua2 = new Quad<Object,Object,Object,Object>(null, "", null, "");
    EQUAL(qua2.getFirst (), null);
    EQUAL(qua2.getSecond(), "");
    EQUAL(qua2.getThird (), null);
    EQUAL(qua2.getFourth(), "");
  }

  public void set_1st_2nd_3rd_4th()
  {
    MSG("4つのオブジェクトを設定するメソッドの確認。");

    Quad<Object,Object,Object,Object> qua;
    qua = new Quad<Object,Object,Object,Object>();
    Object o1 = new Object();
    Object o2 = new Object();
    Object o3 = new Object();
    Object o4 = new Object();

    qua.set(o1, o2, o3, o4);
    EQUAL(qua.getFirst (), o1);
    EQUAL(qua.getSecond(), o2);
    EQUAL(qua.getThird (), o3);
    EQUAL(qua.getFourth(), o4);

    qua.set(
      new Integer(123), new Boolean(true), new Double(0.1234), "あいうえお");
    EQUAL(qua.getFirst (), new Integer(123));
    EQUAL(qua.getSecond(), Boolean.TRUE);
    EQUAL(qua.getThird (), new Double(0.1234));
    EQUAL(qua.getFourth(), "あいうえお");

    qua.set(null, "", null, "");
    EQUAL(qua.getFirst (), null);
    EQUAL(qua.getSecond(), "");
    EQUAL(qua.getThird (), null);
    EQUAL(qua.getFourth(), "");
  }

  public void setFirst()
  {
    MSG("第1オブジェクトを設定するメソッドの確認。");

    Object o1 = new Object();
    Object o2 = new Object();

    Quad<Object,Object,Object,Object> qua;
    qua = new Quad<Object,Object,Object,Object>();
    NULL(qua.getFirst ());
    NULL(qua.getSecond());
    NULL(qua.getThird ());
    NULL(qua.getFourth());

    qua.setFirst(o1);
    EQUAL(qua.getFirst(), o1);
    NULL(qua.getSecond());
    NULL(qua.getThird ());
    NULL(qua.getFourth());

    qua.setFirst(null);
    NULL(qua.getFirst ());
    NULL(qua.getSecond());
    NULL(qua.getThird ());
    NULL(qua.getFourth());

    qua.setFirst(o2);
    EQUAL(qua.getFirst(), o2);
    NULL(qua.getSecond());
    NULL(qua.getThird ());
    NULL(qua.getFourth());
  }
 
  public void setSecond()
  {
    MSG("第2オブジェクトを設定するメソッドの確認。");

    Object o1 = new Object();
    Object o2 = new Object();

    Quad<Object,Object,Object,Object> qua;
    qua = new Quad<Object,Object,Object,Object>();
    NULL(qua.getFirst ());
    NULL(qua.getSecond());
    NULL(qua.getThird ());
    NULL(qua.getFourth());

    qua.setSecond(o1);
    NULL(qua.getFirst());
    EQUAL(qua.getSecond(), o1);
    NULL(qua.getThird ());
    NULL(qua.getFourth());

    qua.setSecond(null);
    NULL(qua.getFirst ());
    NULL(qua.getSecond());
    NULL(qua.getThird ());
    NULL(qua.getFourth());

    qua.setSecond(o2);
    NULL(qua.getFirst());
    EQUAL(qua.getSecond(), o2);
    NULL(qua.getThird ());
    NULL(qua.getFourth());
  }

  public void setThird()
  {
    MSG("第3オブジェクトを設定するメソッドの確認。");

    Object o1 = new Object();
    Object o2 = new Object();

    Quad<Object,Object,Object,Object> qua;
    qua = new Quad<Object,Object,Object,Object>();
    NULL(qua.getFirst ());
    NULL(qua.getSecond());
    NULL(qua.getThird ());
    NULL(qua.getFourth());

    qua.setThird(o1);
    NULL(qua.getFirst());
    NULL(qua.getSecond());
    EQUAL(qua.getThird(), o1);
    NULL(qua.getFourth());

    qua.setThird(null);
    NULL(qua.getFirst ());
    NULL(qua.getSecond());
    NULL(qua.getThird ());
    NULL(qua.getFourth());

    qua.setThird(o2);
    NULL(qua.getFirst());
    NULL(qua.getSecond());
    EQUAL(qua.getThird(), o2);
    NULL(qua.getFourth());
  }

  public void setFourth()
  {
    MSG("第4オブジェクトを設定するメソッドの確認。");

    Object o1 = new Object();
    Object o2 = new Object();

    Quad<Object,Object,Object,Object> qua;
    qua = new Quad<Object,Object,Object,Object>();
    NULL(qua.getFirst ());
    NULL(qua.getSecond());
    NULL(qua.getThird ());
    NULL(qua.getFourth());

    qua.setFourth(o1);
    NULL(qua.getFirst());
    NULL(qua.getSecond());
    NULL(qua.getThird());
    EQUAL(qua.getFourth(), o1);

    qua.setFourth(null);
    NULL(qua.getFirst ());
    NULL(qua.getSecond());
    NULL(qua.getThird ());
    NULL(qua.getFourth());

    qua.setFourth(o2);
    NULL(qua.getFirst());
    NULL(qua.getSecond());
    NULL(qua.getThird());
    EQUAL(qua.getFourth(), o2);
  }

  public void equals()
  {
    MSG("オブジェクトの内容を比較するメソッドの確認。");

    Quad<Object,Object,Object,Object> qua0;
    Quad<Object,Object,Object,Object> qua1;
    Quad<Object,Object,Object,Object> qua2;
    Quad<Object,Object,Object,Object> qua3;
    Quad<Object,Object,Object,Object> qua4;
    Quad<Object,Object,Object,Object> qua5;
    Quad<Object,Object,Object,Object> qua6;
    qua0 = new Quad<Object,Object,Object,Object>();
    qua1 = new Quad<Object,Object,Object,Object>("1", "2", "3", "4");
    qua2 = new Quad<Object,Object,Object,Object>("1", "2", "3", "4");
    qua3 = new Quad<Object,Object,Object,Object>("1", "1", "1", "1");
    qua4 = new Quad<Object,Object,Object,Object>("1", "2", "3", null);
    qua5 = new Quad<Object,Object,Object,Object>("1", "2", null, "4");
    qua6 = new Quad<Object,Object,Object,Object>("1", null, "3", "4");

    FALSE(qua0.equals(null));

    TRUE(qua0.equals(qua0));
    TRUE(qua1.equals(qua1));
    TRUE(qua2.equals(qua2));
    TRUE(qua3.equals(qua3));
    TRUE(qua4.equals(qua4));
    TRUE(qua5.equals(qua5));
    TRUE(qua6.equals(qua6));

    TRUE(qua0.equals(new Quad<Object,Object,Object,Object>()));
    TRUE(qua1.equals(new Quad<Object,Object,Object,Object>(
      "1", "2", "3", "4")));
    TRUE(qua2.equals(new Quad<Object,Object,Object,Object>(
      "1", "2", "3", "4")));
    TRUE(qua3.equals(new Quad<Object,Object,Object,Object>(
      "1", "1", "1", "1")));
    TRUE(qua4.equals(new Quad<Object,Object,Object,Object>(
      "1", "2", "3", null)));
    TRUE(qua5.equals(new Quad<Object,Object,Object,Object>(
      "1", "2", null, "4")));
    TRUE(qua6.equals(new Quad<Object,Object,Object,Object>(
      "1", null, "3", "4")));

    FALSE(qua0.equals(qua1));
    FALSE(qua0.equals(qua2));
    FALSE(qua0.equals(qua3));
    FALSE(qua0.equals(qua4));
    FALSE(qua0.equals(qua5));
    FALSE(qua0.equals(qua6));

    FALSE(qua1.equals(qua0));
    TRUE(qua1.equals(qua2));
    FALSE(qua1.equals(qua3));
    FALSE(qua1.equals(qua4));
    FALSE(qua1.equals(qua5));
    FALSE(qua1.equals(qua6));

    FALSE(qua2.equals(qua0));
    TRUE(qua2.equals(qua1));
    FALSE(qua2.equals(qua3));
    FALSE(qua2.equals(qua4));

    FALSE(qua3.equals(qua0));
    FALSE(qua3.equals(qua1));
    FALSE(qua3.equals(qua2));
    FALSE(qua3.equals(qua4));

    FALSE(qua4.equals(qua0));
    FALSE(qua4.equals(qua1));
    FALSE(qua4.equals(qua2));
    FALSE(qua4.equals(qua3));

    FALSE(qua5.equals(qua1));
    FALSE(qua6.equals(qua1));
  }

  public void _hashCode()
  {
    MSG("ハッシュコードを取得するメソッドの確認。");

    Quad<Object,Object,Object,Object> qua00;
    Quad<Object,Object,Object,Object> qua01;
    Quad<Object,Object,Object,Object> qua10;
    Quad<Object,Object,Object,Object> qua11;
    Quad<Object,Object,Object,Object> qua20;
    Quad<Object,Object,Object,Object> qua21;
    qua00 = new Quad<Object,Object,Object,Object>();
    qua01 = new Quad<Object,Object,Object,Object>();
    qua10 = new Quad<Object,Object,Object,Object>(
      new Integer(1), null, null, null);
    qua11 = new Quad<Object,Object,Object,Object>(
      new Integer(1), null, null, null);
    qua20 = new Quad<Object,Object,Object,Object>(
      new Integer(1), new Integer(1), null, null);
    qua21 = new Quad<Object,Object,Object,Object>(
      new Integer(1), new Integer(1), null, null);

    TRUE (qua00.hashCode() == qua01.hashCode());
    FALSE(qua00.hashCode() == qua11.hashCode());
    FALSE(qua00.hashCode() == qua21.hashCode());
    FALSE(qua10.hashCode() == qua01.hashCode());
    TRUE (qua10.hashCode() == qua11.hashCode());
    FALSE(qua10.hashCode() == qua21.hashCode());
    FALSE(qua20.hashCode() == qua01.hashCode());
    FALSE(qua20.hashCode() == qua11.hashCode());
    TRUE (qua20.hashCode() == qua21.hashCode());
  }

  public void serialize()
  {
    ObjectSerializer os = new ObjectSerializer();

    Quad<Object,Object,Object,Object> qua;
    qua = new Quad<Object,Object,Object,Object>(
      new Long(123L), "あいう", new Integer(11), "a");
    try {
      byte[] bytes = os.serializeToByteArray(qua);
      Quad newQua = Quad.class.cast(os.deserialize(bytes));
      EQUAL(newQua, qua);
    } catch (Exception e) {
      NG(e);
    }
  }
}
