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

import java.util.Iterator;

import junit.framework.TestCase;

/**
 * InvertedIndexのテスト
 * @author satoshi akabane@logical-paradox.org
 * @version $Revision: 1.1 $
 */
public class InvertedIndexTest extends TestCase {

	/**
	 * Constructor for InvertedIndexTest.
	 * @param arg0
	 */
	public InvertedIndexTest(String arg0) {
		super(arg0);
	}
	/**
	 * equals()のテスト
	 * ノードID,blocknoがあっていればOK<br>
	 * ※documentsと位置情報は考慮されない
	 */
	public void testEquals() {
		InvertedIndex a = new InvertedIndex("NODEID00001", 1002, 12);
		InvertedIndex b = new InvertedIndex("NODEID00001", 1002, 292);

		assertEquals(a, b);
	}
	/**
	 * equals()が失敗する場合のテスト
	 * ノードID,blocknoが違えばNG<br>
	 */
	public void testNotEquals() {
		InvertedIndex a = new InvertedIndex("NODEID00001", 1002, 12);
		InvertedIndex b = new InvertedIndex("NODEID00002", 1002, 292);

		assertFalse(a.equals(null));
		assertFalse(a.equals(b));

		b = new InvertedIndex("NODEID00001", 1302, 292);
		assertFalse(a.equals(b));
	}
	/**
	 * hashcodeが同じ場合のテスト
	 */
	public void testHashCodeEquals() {
		InvertedIndex a = new InvertedIndex("NODEID00001", 1002, 12);
		InvertedIndex b = new InvertedIndex("NODEID00001", 1002, 292);

		assertEquals(a.hashCode(), b.hashCode());
	}
	/**
	 * hashcodeが違う場合のテスト
	 */
	public void testHashCodeNotEquals() {
		InvertedIndex a = new InvertedIndex("NODEID00001", 1002, 12);
		InvertedIndex b = new InvertedIndex("NODEID00002", 1002, 292);

		assertFalse(a.hashCode() == b.hashCode());

		b = new InvertedIndex("NODEID00001", 1003, 12);
		assertFalse(a.hashCode() == b.hashCode());
	}
	/**
	 * equals()とhashCode()の相互関連性に関するテスト
	 */
	public void testEqualsAndHashCodeRelation() {
		InvertedIndex a = new InvertedIndex("NODEID00001", 1002, 12);
		InvertedIndex b = new InvertedIndex("NODEID00001", 1002, 292);

		assertTrue(a.equals(b) && a.hashCode() == b.hashCode());
	}
	/**
	 * getLocation()のテスト
	 */
	public void testGettingLocation() {
		InvertedIndex src = new InvertedIndex("NODE00001", 2999, 121);
		Location l1 = new Location("NODE00001", 32768, 1992);
		Location l2 = new Location("NODE00001", 16384, 999);
		src.addLocation(l1);
		src.addLocation(l2);

		// 存在するもの
		assertSame(l1, src.getLocation(32768, 1992));
		assertSame(l2, src.getLocation(16384, 999));
		// 存在しないもの
		assertNotSame(l1, src.getLocation(16383, 332));
	}
	/**
	 * 位置情報削除のテスト
	 */
	public void testRemovingLocation() {
		InvertedIndex src = new InvertedIndex("NODE00001", 1, 3);		// 64,65がon
		Location l1 = new Location("NODE00001", 64, 1992);
		Location l2 = new Location("NODE00001", 65, 999);
		Location l3 = new Location("NODE00001", 65, 1024);
		src.addLocation(l1);
		src.addLocation(l2);
		src.addLocation(l3);

		// l1を削除する
		// docno=64に1つか位置情報がないので,documentsが2に変化する
		src.removeLocation(new Location("NODE00001", 64, 1992));

		assertNull(src.getLocation(64,1992));
		assertEquals(2, src.getDocumentAvailability());

		// l2を削除する
		// docno=65には2つあるので、片方削ってもまだある
		src.removeLocation(new Location("NODE00001", 65, 999));
		assertNull(src.getLocation(65,999));
		assertNotNull(src.getLocation(65, 1024));
		assertEquals(2, src.getDocumentAvailability());
	}
	/**
	 * 転置情報の再設定のテスト
	 * リセットされたものについて、位置情報が削除されていること
	 */
	public void testResetDocumentAvailability() {
		InvertedIndex src = new InvertedIndex("NODE00001", 1, 3);		// 64,65がon
		Location l1 = new Location("NODE00001", 64, 1992);
		Location l2 = new Location("NODE00001", 65, 999);
		Location l3 = new Location("NODE00001", 65, 1024);
		src.addLocation(l1);
		src.addLocation(l2);
		src.addLocation(l3);

		// documents = 1に設定(l2とl3が削除される)
		src.setDocumentAvailability(1);

		// l1はある
		assertNotNull(src.getLocation(64, 1992));
		// l2はない
		assertNull(src.getLocation(65, 999));
		// l3もない
		assertNull(src.getLocation(65, 1024));
	}
	/**
	 * 位置情報イテレータのテスト
	 * 違う文書番号でも、正しく連結したリストとして参照できることを確認する
	 */
	public void testLocationIterator() {
		InvertedIndex src = new InvertedIndex("NODE00001", 1, 3);		// 64,65がon
		Location l1 = new Location("NODE00001", 64, 1992);
		Location l2 = new Location("NODE00001", 65, 999);
		Location l3 = new Location("NODE00001", 65, 1024);
		src.addLocation(l1);
		src.addLocation(l2);
		src.addLocation(l3);

		Iterator it = src.iteratorLocations();
		Object o = it.next();
		assertTrue(l1 == o || l2 == o || l3 == o);
		o = it.next();
		assertTrue(l1 == o || l2 == o || l3 == o);
		o = it.next();
		assertTrue(l1 == o || l2 == o || l3 == o);

		// もうないはず
		assertFalse(it.hasNext());
	}
	/**
	 * コピーコンストラクタのテスト
	 */
	public void testCopyConstructor() {
		InvertedIndex src = new InvertedIndex("NODE00001", 2999, 121);
		Location l1 = new Location("NODE00001", 32768, 1992);
		Location l2 = new Location("NODE00001", 16384, 999);
		src.addLocation(l1);
		src.addLocation(l2);

		InvertedIndex dst = new InvertedIndex(src);
		assertEquals(src.getNodeId(), dst.getNodeId());
		assertEquals(src.getBlockNo(), dst.getBlockNo());
		assertEquals(src.getDocumentAvailability(), dst.getDocumentAvailability());

		assertEquals(src, dst);

		// 位置情報の比較
		// 位置情報は同じインスタンスが取得できる
		assertSame(src.getLocation(32768, 1992), dst.getLocation(32768, 1992));
		assertSame(src.getLocation(16384, 999), dst.getLocation(16384, 999));
	}
	/**
	 * clone()のテスト
	 */
	public void testClone() throws CloneNotSupportedException {
		InvertedIndex src = new InvertedIndex("NODE00001", 2999, 121);
		Location l1 = new Location("NODE00001", 32768, 1992);
		Location l2 = new Location("NODE00001", 16384, 999);
		src.addLocation(l1);
		src.addLocation(l2);

		InvertedIndex dst = (InvertedIndex)src.clone();
		assertEquals(src.getNodeId(), dst.getNodeId());
		assertEquals(src.getBlockNo(), dst.getBlockNo());
		assertEquals(src.getDocumentAvailability(), dst.getDocumentAvailability());

		assertEquals(src, dst);

		// 位置情報の比較
		// 位置情報は同じインスタンスが取得できる
		assertSame(src.getLocation(32768, 1992), dst.getLocation(32768, 1992));
		assertSame(src.getLocation(16384, 999), dst.getLocation(16384, 999));
	}
}
