/*
 * TriggerTest 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.table;

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

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

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

  /* -- inner class -- */

  class TriggerEx<C,V> extends Trigger<C,V> {}
  
  static class TableEx<C,V> extends AbstractTable<C,V> {
    final static long serialVersionUID = 0L;
    public TableEx() {}
    public TableEx(int nrec, int ncol) { super(nrec, ncol); }
    public TableEx(Header<C> h) { super(h); }
    @Override 
    protected Header<C> createHeader(int nc) {
      return new Header<C>() {
        static final long serialVersionUID = 0L;
        Set<C> columnSet_ = new HashSet<C>();
        public int columnCount() { return columnSet_.size(); }
        public Enumeration<C> columns() {
          return Collections.enumeration(columnSet_);
        }
        public boolean hasColumn(Object c) { return columnSet_.contains(c); }
        public void addColumn(C c) { columnSet_.add(c); }
      };
    }
    @Override
    protected Collection<Record<C,V>> createRecordCollection(int nc) {
      return new LinkedList<Record<C,V>>();
    }
    @Override
    protected Record<C,V> createRecord(int nc) {
      return new Record<C,V>() {
        static final long serialVersionUID = 0L;
        private Map<C,V> map_ = new HashMap<C,V>();
        protected Header<C> header() { return TableEx.this.header(); }
        protected V getValue(Object c) { return map_.get(c); }
        protected V putValue(C c, V v) { return map_.put(c, v); }
        protected V removeValue(Object c) { return map_.remove(c); }
      };
    }
  }

  /* -- test case -- */

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

    Trigger<String,Object> t = new TriggerEx<String,Object>();
    NOTNULL(t);
  }

  public void prePostMethods()
  {
    MSG("pre〜,post〜メソッドを単に実行。");

    Trigger<String,Object> trg = new TriggerEx<String,Object>();
    Table<String,Object> tab = new TableEx<String,Object>();
    Map<String,Object> rec = new HashMap<String,Object>();
    Map<String,Object> dst = new HashMap<String,Object>();

    trg.preAppend(tab, rec);
    trg.postAppend(tab, rec);
    trg.preUpdate(tab, rec, dst);
    trg.postUpdate(tab, rec, dst);
    trg.preDelete(tab, rec);
    trg.postDelete(tab, rec);
  }

  public void createClone()
  {
    MSG("クローン・オブジェクトの作成");

    Trigger<String,Object> t = new TriggerEx<String,Object>();
    Trigger<String,Object> t0 = t.createClone();

    EQUAL(t0.getClass(), TriggerEx.class);
  }

  public void prePostDeleteAll()
  {
    MSG("レコードを全削除する直前・直後に呼ばれるメソッド。");

    final Table<String,Object> tab = new TableEx<String,Object>();
    final Map<String,Object> rec0 = tab.appendNew();
    final Map<String,Object> rec1 = tab.appendNew();

    Trigger<String,Object> trg = new TriggerEx<String,Object>() {
      private int count = 0;
      public void preDelete(Table<String,Object> t, Map<String,Object> r) {
        count ++;
        EQUAL(t, tab);
        if (count == 1) { EQUAL(r, rec0); }
        else if (count == 2) { EQUAL(r, rec1); }
      }
      public void postDelete(Table<String,Object> t, Map<String,Object> r) {
        EQUAL(t, tab);
        if (count == 1) { EQUAL(r, rec0); }
        else if (count == 2) { EQUAL(r, rec1); }
      }
    };
    tab.addTrigger(trg);

    tab.deleteAll();
  }
}

