/*
 * LOGICAL-PARADOX.ORG
 * Copyright (C)2005 satoshi akabane(akabane@logical-paradox.org)
 * $Id: RSSSearchEngineTest.java,v 1.3 2005/11/06 14:46:32 rampil Exp $
 */
package org.logical_paradox.koike.rss.search;

import java.util.List;
import java.util.Properties;

import junit.framework.TestCase;

import org.logical_paradox.koike.core.KoikeConfig;
import org.logical_paradox.koike.core.KoikeConstant;
import org.logical_paradox.koike.core.search.Element;
import org.logical_paradox.koike.core.search.KoikeIndexResultSet;
import org.logical_paradox.koike.core.search.ResultSet;
import org.logical_paradox.koike.core.search.SearchCondition;
import org.logical_paradox.koike.core.search.SearchException;
import org.logical_paradox.koike.core.search.SearchResult;
import org.logical_paradox.koike.tools.isys.StubIndexAccessor;

/**
 * RSS/1bサーチエンジンのテスト
 * @author satoshi akabane@logical-paradox.org
 * @version $Revision: 1.3 $
 */
public class RSSSearchEngineTest extends TestCase {
	/** テスト用サーチエンジンのインスタンス */
	private RSSSearchEngineImpl searchEngine;

	/**
	 * Constructor for RSSSearchEngineTest.
	 * @param arg0
	 */
	public RSSSearchEngineTest(String arg0) {
		super(arg0);
	}

	/**
	 * 検索語を探すテスト01
	 * 何かしらひっかかる条件でテスト
	 */
	public void testExecuteQueryAndFoundAnswers() throws SearchException {
		KoikeIndexResultSet rs = searchEngine.executeQuery("サーチエンジン");

		assertNotNull(rs);
		assertFalse(rs.isEmpty());
	}
	/**
	 * 検索語を探すテスト02
	 * 何もひっかからない条件でテスト
	 */
	public void testExecuteQueryAndNotFound() throws SearchException {
		KoikeIndexResultSet rs = searchEngine.executeQuery("インデクス");

		assertNull(rs);
	}
	/**
	 * 検索語を探すテスト03
	 * 索引語長より短い文字列で検索しようとした場合のテスト
	 */
	public void testExecuteQueryWith1Letter() {
		try {
			searchEngine.executeQuery("イ");
			fail();
		} catch(SearchException se) {
			// OK
		}
	}
	/**
	 * 検索語1語のAND検索
	 */
	public void testSearchWith1Word() throws SearchException {
		// まず検索条件を作成する
		// <AND>
		//   <TERM>Open-SEDK</TERM>
		// </AND>
		SearchCondition condition = new SearchCondition();
		condition.setDispnum(10);
		condition.setStartp(0);

		Element e = new Element(Element.TYPE_TERM, "Open-SEDK");
		condition.addChildNode(e);

		// 検索処理
		SearchResult sr = searchEngine.search(condition);
		ResultSet[] results = sr.getResultSet();

		// NODE00001:01:0,60,320,535,546,596,945,1057
		// NODE00001:02:338,1423
		assertNotNull(results);
		assertTrue(results.length == 2);
	}
	/**
	 * 検索語1語のAND検索で、かつ検索結果がない場合のテスト
	 */
	public void testSearchAndNotFound() throws SearchException {
		// まず検索条件を作成する
		// <AND>
		//   <TERM>Open-SEDK</TERM>
		// </AND>
		SearchCondition condition = new SearchCondition();
		condition.setDispnum(10);
		condition.setStartp(0);

		Element e = new Element(Element.TYPE_TERM, "Open-SpDK");
		condition.addChildNode(e);

		// 検索処理
		SearchResult sr = searchEngine.search(condition);
		assertNull(sr);
	}
	/**
	 * 検索語2語のAND検索
	 */
	public void testSearchWith2Word() throws SearchException {
		// まず検索条件を作成する
		// <AND>
		//   <TERM>Open-SEDK</TERM>
		//   <TERM>secure</TERM>
		// </AND>
		SearchCondition condition = new SearchCondition();
		condition.setDispnum(10);
		condition.setStartp(0);

		condition.addChildNode(new Element(Element.TYPE_TERM, "Open-SEDK"));
		condition.addChildNode(new Element(Element.TYPE_TERM, "SETI@homeみたいな感じ"));
		// 検索処理
		SearchResult sr = searchEngine.search(condition);
		ResultSet[] results = sr.getResultSet();

		// NODE00001:01
		assertNotNull(results);
		assertTrue(results.length == 1);
	}
	/**
	 * テスト用のセットアップ
	 */
	protected void setUp() throws Exception {
		super.setUp();
		// テスト用のラッパーを生成する
		Properties p = new Properties();
		// 具象インターフェースファクトリ
		p.setProperty(KoikeConstant.KEY_INTERFACE_FACTORY, "org.logical_paradox.koike.tools.isys.StubConcreteInterfaceFactory");
		// n-gram長
		p.setProperty(KoikeConstant.KEY_N_GRAM_TERM_LENGTH, "2");
		KoikeConfig config = new KoikeConfig(p);

		searchEngine = new RSSSearchEngineImpl(config);
	}

	/**
	 * テスト用のラッパークラス
	 * @author satoshi akabane@logical-paradox.org
	 * @version $Revision: 1.3 $
	 */
	class RSSSearchEngineImpl extends RSSSearchEngine {
		/**
		 * コンストラクタ
		 * @param config コンフィグレーション
		 * @throws Exception インスタンスの生成に失敗
		 */
		public RSSSearchEngineImpl(KoikeConfig config) throws Exception {
			super(config);
		}
		/**
		 * executeQuery()をpublicで公開するためのラッパーメソッド
		 */
		public KoikeIndexResultSet executeQuery(String keyword) throws SearchException {
			return super.executeQuery(keyword);
		}
		/**
		 * このサーチエンジン(スタブ)の初期化処理
		 * SearchEngine#init()をオーバーライドするため
		 */
		protected void init() throws Exception {
			// インデックスアクセサを初期化する(インデックスファイルのロード)
			StubIndexAccessor stubixr = (StubIndexAccessor)getIndexAccessor();
			stubixr.load();
		}

		/**
		 * 要素を問い合わせて結果を取得する
		 */
		public KoikeIndexResultSet retrieve(List searchWords, Element element) throws SearchException {
			return super.retrieve(searchWords, element);
		}
	}
}
