/*
 * LOGICAL-PARADOX.ORG
 * Copyright (C)2005 satoshi akabane(akabane@logical-paradox.org)
 * $Id: AndLogicalOperatorTest.java,v 1.1 2005/05/31 14:38:20 rampil Exp $
 */
package org.logical_paradox.koike.rss.search.lo;

import org.logical_paradox.koike.core.search.Element;
import org.logical_paradox.koike.core.search.InvertedIndex;
import org.logical_paradox.koike.core.search.KoikeIndexResultSet;

import junit.framework.TestCase;

/**
 * AND論理演算子のテスト
 * @author satoshi akabane@logical-paradox.org
 * @version $Revision: 1.1 $
 */
public class AndLogicalOperatorTest extends TestCase {
	/** 論理演算子 */
	private LogicalOperator op;

	/**
	 * Constructor for AndLogicalOperatorTest.
	 * @param arg0
	 */
	public AndLogicalOperatorTest(String arg0) {
		super(arg0);
	}
	/**
	 * 引数がnullまたは0の場合
	 * nullが返却される
	 */
	public void testOperationWithNullArgument() throws LogicalOperationException {
		// 引数がnull
		assertNull(op.execute(null));
		// 引数が空
		assertNull(op.execute(new KoikeIndexResultSet[] {}));
	}
	/**
	 * AND演算の対象が1つの場合
	 * 引数として指定した値がそのまま返る
	 */
	public void testOperationWithSingleArgument() throws LogicalOperationException {
		KoikeIndexResultSet rs = new KoikeIndexResultSet();
		rs.addInvertedIndex(new InvertedIndex("NODE00001", 100, 20));
		rs.addInvertedIndex(new InvertedIndex("NODE00002", 100, 20));
		rs.addInvertedIndex(new InvertedIndex("NODE00002", 103, 15));

		KoikeIndexResultSet results[] = op.execute(new KoikeIndexResultSet[] {rs});

		assertNotNull(results);
		assertTrue(results.length > 0);
		assertSame(rs, results[0]);
	}
	/**
	 * AND演算を適用した結果、結果が0の場合
	 */
	public void testNoResult() throws LogicalOperationException {
		KoikeIndexResultSet rs1 = new KoikeIndexResultSet();
		rs1.addInvertedIndex(new InvertedIndex("NODE00001", 100, 20));
		rs1.addInvertedIndex(new InvertedIndex("NODE00002", 100, 20));
		rs1.addInvertedIndex(new InvertedIndex("NODE00002", 103, 15));

		KoikeIndexResultSet rs2 = new KoikeIndexResultSet();
		rs2.addInvertedIndex(new InvertedIndex("NODE00003", 100, 20));
		rs2.addInvertedIndex(new InvertedIndex("NODE00002", 104, 20));
		rs2.addInvertedIndex(new InvertedIndex("NODE00002", 99, 15));

		KoikeIndexResultSet results[] = op.execute(new KoikeIndexResultSet[] {rs1, rs2});
		assertNull(results);
	}
	/**
	 * AND演算を適用した結果、1つだけ一致した場合のテスト
	 * <li>一致しない転置インデックスが破棄されていること</li>
	 * <li>一致した転置インデックスについて、正しくdocumentsが設定されていること</li>
	 */
	public void testMatchPattern01() throws LogicalOperationException {
		KoikeIndexResultSet rs1 = new KoikeIndexResultSet();
		rs1.addInvertedIndex(new InvertedIndex("NODE00001", 100, 20));
		rs1.addInvertedIndex(new InvertedIndex("NODE00002", 100, 20));
		rs1.addInvertedIndex(new InvertedIndex("NODE00002", 103, 15));

		KoikeIndexResultSet rs2 = new KoikeIndexResultSet();
		rs2.addInvertedIndex(new InvertedIndex("NODE00003", 100, 20));
		rs2.addInvertedIndex(new InvertedIndex("NODE00002", 100, 7));
		rs2.addInvertedIndex(new InvertedIndex("NODE00002", 99, 15));

		KoikeIndexResultSet results[] = op.execute(new KoikeIndexResultSet[] {rs1, rs2});
		assertNotNull(results);
		assertTrue(results.length > 0);

		KoikeIndexResultSet result = results[0];
		assertNull(result.getInvertedIndex("NODE00001", 100));
		assertNotNull(result.getInvertedIndex("NODE00002", 100));
		assertNull(result.getInvertedIndex("NODE00002", 103));

		// 20 & 7 = 4(documents)
		assertEquals(4L, result.getInvertedIndex("NODE00002", 100).getDocumentAvailability());
	}
	/**
	 * AND演算を適用した結果、2つ一致した場合のテスト
	 * 索引語を3つでトライする
	 * <li>一致しない転置インデックスが破棄されていること</li>
	 * <li>一致し	た転置インデックスについて、正しくdocumentsが設定されていること</li>
	 */
	public void testMatchPattern02() throws LogicalOperationException {
		// 索引語1
		KoikeIndexResultSet rs1 = new KoikeIndexResultSet();
		rs1.addInvertedIndex(new InvertedIndex("NODE00001", 100, 20));
		rs1.addInvertedIndex(new InvertedIndex("NODE00002", 100, 20));
		rs1.addInvertedIndex(new InvertedIndex("NODE00002", 99, 21));
		// 索引語2
		KoikeIndexResultSet rs2 = new KoikeIndexResultSet();
		rs2.addInvertedIndex(new InvertedIndex("NODE00003", 100, 20));
		rs2.addInvertedIndex(new InvertedIndex("NODE00002", 100, 7));
		rs2.addInvertedIndex(new InvertedIndex("NODE00002", 99, 13));
		// 索引語3
		KoikeIndexResultSet rs3 = new KoikeIndexResultSet();
		rs3.addInvertedIndex(new InvertedIndex("NODE00002", 100, 20));
		rs3.addInvertedIndex(new InvertedIndex("NODE00004", 10, 50));
		rs3.addInvertedIndex(new InvertedIndex("NODE00002", 99, 6));

		KoikeIndexResultSet results[] = op.execute(new KoikeIndexResultSet[] {rs1, rs2, rs3});
		assertNotNull(results);
		assertTrue(results.length > 0);

		KoikeIndexResultSet result = results[0];
		assertNull(result.getInvertedIndex("NODE00001", 100));
		assertNull(result.getInvertedIndex("NODE00003", 100));
		assertNull(result.getInvertedIndex("NODE00004", 10));

		assertNotNull(result.getInvertedIndex("NODE00002", 99));
		assertNotNull(result.getInvertedIndex("NODE00002", 100));

		// 21 & 13 & 6 = 4(documents)
		assertEquals(4L, result.getInvertedIndex("NODE00002", 99).getDocumentAvailability());
		// 20 & 7 & 20 = 4(documents)
		assertEquals(4L, result.getInvertedIndex("NODE00002", 100).getDocumentAvailability());
	}
	/**
	 * テストケースの初期化
	 */
	protected void setUp() throws Exception {
		super.setUp();
		op = LogicalOperatorFactory.getOperator(Element.TYPE_AND);
	}

}
