/*
 * TrioTest 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>Trio</code>クラスの機能試験クラス。
 *
 * @author  佐藤隆之. 
 * @version $Revision: 1.1.1.1 $, $Date: 2010-10-16 00:03:45 $
 */
public class TrioTest 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(TrioTest.class, (args.length == 0) ? null : args[0]);
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }

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

  /* -- text case -- */

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

    Trio<Object,Object,Object> trio = new Trio<Object,Object,Object>();
    NULL(trio.getFirst());
    NULL(trio.getSecond());
    NULL(trio.getThird());

    Trio<Integer,Integer,Integer> trio2 = new Trio<Integer,Integer,Integer>();
    NULL(trio2.getFirst());
    NULL(trio2.getSecond());
    NULL(trio2.getThird());
  }
  
  public void constructor_first_second_third()
  {
    MSG("3つのオブジェクトを引数にとるコンストラクタの確認。");

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

    Trio<Object,Object,Object> trio = new Trio<Object,Object,Object>(o1,o2,o3);
    EQUAL(trio.getFirst(), o1);
    EQUAL(trio.getSecond(), o2);
    EQUAL(trio.getThird(), o3);

    Trio<Long,String,Boolean> t2 = new Trio<Long,String,Boolean>(1L, "a", true);
    EQUAL(t2.getFirst().longValue(), 1L);
    EQUAL(t2.getSecond(), "a");
    EQUAL(t2.getThird().booleanValue(), true);

    Trio<Long,String,Boolean> t = new Trio<Long,String,Boolean>(null,null,null);
    NULL(t.getFirst());
    NULL(t.getSecond());
    NULL(t.getThird());
  }

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

    Trio<Object,Object,Object> trio = new Trio<Object,Object,Object>();
    Object o1 = new Object();
    Object o2 = new Object();
    Object o3 = new Object();
    trio.set(o1, o2, o3);
    EQUAL(trio.getFirst(), o1);
    EQUAL(trio.getSecond(), o2);
    EQUAL(trio.getThird(), o3);

    Trio<Long,String,Boolean> t2 = new Trio<Long,String,Boolean>();
    t2.set(1L, "a", true);
    EQUAL(t2.getFirst().longValue(), 1L);
    EQUAL(t2.getSecond(), "a");
    EQUAL(t2.getThird().booleanValue(), true);

    t2.set(null,null,null);
    NULL(t2.getFirst());
    NULL(t2.getSecond());
    NULL(t2.getThird());
  }

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

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

    Trio<Object,Object,Object> trio = new Trio<Object,Object,Object>();
    trio.setFirst(o1);
    EQUAL(trio.getFirst(), o1);
    EQUAL(trio.getSecond(), null);
    EQUAL(trio.getThird(), null);
    trio.setFirst(o2);
    EQUAL(trio.getFirst(), o2);
    EQUAL(trio.getSecond(), null);
    EQUAL(trio.getThird(), null);
    trio.setFirst(o3);
    EQUAL(trio.getFirst(), o3);
    EQUAL(trio.getSecond(), null);
    EQUAL(trio.getThird(), null);

    Trio<Object,Object,Object> trio1 = new Trio<Object,Object,Object>();
    trio1.setFirst(new Integer(987));
    EQUAL(trio1.getFirst(), new Integer(987));
    EQUAL(trio1.getSecond(), null);
    EQUAL(trio1.getThird(), null);
    trio1.setFirst(new Boolean(true));
    EQUAL(trio1.getFirst(), new Boolean(true));
    EQUAL(trio1.getSecond(), null);
    EQUAL(trio1.getThird(), null);
    trio1.setFirst("あかさたな");
    EQUAL(trio1.getFirst(), "あかさたな");
    EQUAL(trio1.getSecond(), null);
    EQUAL(trio1.getThird(), null);

    Trio<Object,Object,Object> trio2 = new Trio<Object,Object,Object>();
    trio2.setFirst("");
    EQUAL(trio2.getFirst(), "");
    EQUAL(trio2.getSecond(), null);
    EQUAL(trio2.getThird(), null);
    trio2.setFirst(null);
    EQUAL(trio2.getFirst(), null);
    EQUAL(trio2.getSecond(), null);
    EQUAL(trio2.getThird(), null);
    trio2.setFirst("  ");
    EQUAL(trio2.getFirst(), "  ");
    EQUAL(trio2.getSecond(), null);
    EQUAL(trio2.getThird(), null);
  }

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

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

    Trio<Object,Object,Object> trio = new Trio<Object,Object,Object>();
    trio.setSecond(o1);
    EQUAL(trio.getSecond(), o1);
    EQUAL(trio.getFirst(), null);
    EQUAL(trio.getThird(), null);
    trio.setSecond(o2);
    EQUAL(trio.getSecond(), o2);
    EQUAL(trio.getFirst(), null);
    EQUAL(trio.getThird(), null);
    trio.setSecond(o3);
    EQUAL(trio.getSecond(), o3);
    EQUAL(trio.getFirst(), null);
    EQUAL(trio.getThird(), null);

    Trio<Object,Object,Object> trio1 = new Trio<Object,Object,Object>();
    trio1.setSecond(new Integer(987));
    EQUAL(trio1.getSecond(), new Integer(987));
    EQUAL(trio1.getFirst(), null);
    EQUAL(trio1.getThird(), null);
    trio1.setSecond(new Boolean(true));
    EQUAL(trio1.getSecond(), new Boolean(true));
    EQUAL(trio1.getFirst(), null);
    EQUAL(trio1.getThird(), null);
    trio1.setSecond("あかさたな");
    EQUAL(trio1.getSecond(), "あかさたな");
    EQUAL(trio1.getFirst(), null);
    EQUAL(trio1.getThird(), null);

    Trio<Object,Object,Object> trio2 = new Trio<Object,Object,Object>();
    trio2.setSecond("");
    EQUAL(trio2.getSecond(), "");
    EQUAL(trio2.getFirst(), null);
    EQUAL(trio2.getThird(), null);
    trio2.setSecond(null);
    EQUAL(trio2.getSecond(), null);
    EQUAL(trio2.getFirst(), null);
    EQUAL(trio2.getThird(), null);
    trio2.setSecond("  ");
    EQUAL(trio2.getSecond(), "  ");
    EQUAL(trio2.getFirst(), null);
    EQUAL(trio2.getThird(), null);
  }

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

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

    Trio<Object,Object,Object> trio = new Trio<Object,Object,Object>();
    trio.setThird(o1);
    EQUAL(trio.getThird(), o1);
    EQUAL(trio.getFirst(), null);
    EQUAL(trio.getSecond(), null);
    trio.setThird(o2);
    EQUAL(trio.getThird(), o2);
    EQUAL(trio.getFirst(), null);
    EQUAL(trio.getSecond(), null);
    trio.setThird(o3);
    EQUAL(trio.getThird(), o3);
    EQUAL(trio.getFirst(), null);
    EQUAL(trio.getSecond(), null);

    Trio<Object,Object,Object> trio1 = new Trio<Object,Object,Object>();
    trio1.setThird(new Integer(987));
    EQUAL(trio1.getThird(), new Integer(987));
    EQUAL(trio1.getFirst(), null);
    EQUAL(trio1.getSecond(), null);
    trio1.setThird(new Boolean(true));
    EQUAL(trio1.getThird(), new Boolean(true));
    EQUAL(trio1.getFirst(), null);
    EQUAL(trio1.getSecond(), null);
    trio1.setThird( "あかさたな");
    EQUAL(trio1.getThird(), "あかさたな");
    EQUAL(trio1.getFirst(), null);
    EQUAL(trio1.getSecond(), null);

    Trio<Object,Object,Object> trio2 = new Trio<Object,Object,Object>();
    trio2.setThird("");
    EQUAL(trio2.getThird(), "");
    EQUAL(trio2.getFirst(), null);
    EQUAL(trio2.getSecond(), null);
    trio2.setThird(null);
    EQUAL(trio2.getThird(), null);
    EQUAL(trio2.getFirst(), null);
    EQUAL(trio2.getSecond(), null);
    trio2.setThird("  ");
    EQUAL(trio2.getThird(), "  ");
    EQUAL(trio2.getFirst(), null);
    EQUAL(trio2.getSecond(), null);
  }

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

    Trio<String,String,String> trio0;
    Trio<String,String,String> trio1;
    Trio<String,String,String> trio2;
    Trio<String,String,String> trio3;
    Trio<String,String,String> trio4;
    Trio<String,String,String> trio5;
    Trio<String,String,String> trio6;
    trio0 = new Trio<String,String,String>();
    trio1 = new Trio<String,String,String>("1", "2", "3");
    trio2 = new Trio<String,String,String>("1", "1", "1");
    trio3 = new Trio<String,String,String>("2", "2", "2");
    trio4 = new Trio<String,String,String>("1", "2", "3");
    trio5 = new Trio<String,String,String>("1", "2", null);
    trio6 = new Trio<String,String,String>("1", null, "3");

    TRUE(trio0.equals(trio0));
    TRUE(trio1.equals(trio1));
    TRUE(trio2.equals(trio2));
    TRUE(trio3.equals(trio3));
    TRUE(trio4.equals(trio4));
    TRUE(trio5.equals(trio5));
    TRUE(trio6.equals(trio6));

    TRUE(trio0.equals(new Trio()));
    FALSE(trio0.equals(null));
    FALSE(trio0.equals(trio1));
    FALSE(trio0.equals(trio2));
    FALSE(trio0.equals(trio3));
    FALSE(trio0.equals(trio4));
    FALSE(trio0.equals(trio5));
    FALSE(trio0.equals(trio6));

    FALSE(trio1.equals(trio0));
    FALSE(trio1.equals(trio2));
    FALSE(trio1.equals(trio3));
    TRUE (trio1.equals(trio4));
    FALSE(trio1.equals(trio5));
    FALSE(trio1.equals(trio6));

    FALSE(trio5.equals(trio1));
    FALSE(trio6.equals(trio1));
  }

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

    Trio<Object,Object,Object> trio00 = new Trio<Object,Object,Object>();
    Trio<Object,Object,Object> trio01 = new Trio<Object,Object,Object>();
    EQUAL(trio00.hashCode(), trio01.hashCode());

    Trio<Object,Object,Object> trio10;
    Trio<Object,Object,Object> trio11;
    trio10 = new Trio<Object,Object,Object>(new Integer(123), null, null);
    trio11 = new Trio<Object,Object,Object>(new Integer(123), null, null);
    EQUAL(trio10.hashCode(), trio11.hashCode());

    Trio<Object,Object,Object> trio20;
    Trio<Object,Object,Object> trio21;
    trio20 = new Trio<Object,Object,Object>(null, new Double(3.14159), "ABC");
    trio21 = new Trio<Object,Object,Object>(null, new Double(3.14159), "ABC");
    EQUAL(trio20.hashCode(), trio21.hashCode());

    Trio<Object,Object,Object> trio30;
    trio30 = new Trio<Object,Object,Object>(new Long(369L), "あいうえお",
      new Duo<String,String>("a","b"));
    Trio<Object,Object,Object> trio31;
    trio31 = new Trio<Object,Object,Object>(new Long(369L), "あいうえお",
      new Duo<String,String>("a","b"));
    EQUAL(trio30.hashCode(), trio31.hashCode());
  }

  public void serialize()
  {
    MSG("シリアライズの確認。");

    ObjectSerializer os = new ObjectSerializer();

    Trio<Long,String,Duo<String,String>> trio0;
    trio0 = new Trio<Long,String,Duo<String,String>>();
    trio0.set(new Long(369L), "あいうえお", new Duo<String,String>("a","b"));

    try {
      byte[] bytes = os.serializeToByteArray(trio0);
      Trio newTrio = Trio.class.cast(os.deserialize(bytes));
      EQUAL(newTrio, trio0);
    } catch (Exception e) {
      NG(e);
    }
  }
}
