package junkutil.set;

import java.util.Arrays;
import java.util.List;
import java.util.Vector;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import junkutil.set.LzList;

/**
 * LzListTestをテストする。
 */
public class LzListTest extends TestCase {
	/**
	 * コンストラクタ
	 * @param name
	 */
	public LzListTest(String name) {
		super(name);
	}

	/**
	 * @return
	 */
	public static Test suite() {
		TestSuite test = new TestSuite("LzListTest");
		test.addTest(new TestSuite(LzListTest.class));
		return test;
	}

	/**
	 * @see junit.framework.TestCase#setUp()
	 */
	protected void setUp() throws Exception {
	}

	/**
	 * @see junit.framework.TestCase#tearDown()
	 */
	protected void tearDown() throws Exception {
	}

	/**
	 * @throws Exception
	 */
	public void testOr() throws Exception {
		List list = Arrays.asList(new String[]{"A", "B", "C"});
		List list2 = Arrays.asList(new String[]{"B", "C", "D", "E"});
		List or = new LzList(list).or(list2).sortAsc().list();
		assertTrue(or.toString().equals("[A, B, C, D, E]"));
	}
	
	/**
	 * @throws Exception
	 */
	public void testAnd() throws Exception {
		List list = Arrays.asList(new String[]{"A", "B", "C"});
		List list2 = Arrays.asList(new String[]{"B", "C", "D", "E"});
		List and = new LzList(list).and(list2).sortAsc().list();
		assertTrue(and.toString().equals("[B, C]"));
	}
	
	/**
	 * @throws Exception
	 */
	public void testSortAsc() throws Exception {
		List list = Arrays.asList(new String[]{"BB", "A", "CCC"});
		List asc = new LzList(list).sortAsc().list();
		assertTrue(asc.toString().equals("[A, BB, CCC]"));
	}
	
	/**
	 * @throws Exception
	 */
	public void testSortDesc() throws Exception {
		List list = Arrays.asList(new String[]{"BB", "A", "CCC"});
		List desc = new LzList(list).sortDesc().list();
		assertTrue(desc.toString().equals("[CCC, BB, A]"));
	}
	
	/**
	 * @throws Exception
	 */
	public void testJoin() throws Exception {
		List list = Arrays.asList(new String[]{"A", "B"});
		List list2 = Arrays.asList(new String[]{"B", "C"});
		List join = new LzList(list).join(list2).list();
		assertTrue(join.toString().equals("[A, B, B, C]"));
	}
	
	/**
	 * @throws Exception
	 */
	public void testUniq() throws Exception {
		List list = Arrays.asList(new String[]{"BB", "A", "CCC", "BB"});
		List uniq = new LzList(list).uniq().list();
		assertTrue(uniq.toString().equals("[BB, A, CCC]"));
	}

	/**
	 * @throws Exception
	 */
	public void testReverse() throws Exception {
		List list = Arrays.asList(new String[]{"A", "BB", "CCC"});
		List reverse = new LzList(list).reverse().list();
		assertTrue(reverse.toString().equals("[CCC, BB, A]"));

		List list2 = Arrays.asList(new String[]{});
		List reverse2 = new LzList(list2).reverse().list();
		assertTrue(reverse2.toString().equals("[]"));
	}

	/**
	 * @throws Exception
	 */
	public void notNull() throws Exception {
		List list = Arrays.asList(new String[]{"A", "BB", null, "CCC", null});
		List notNull = new LzList(list).notNull().list();
		assertTrue(notNull.toString().equals("[A, BB, CCC]"));
	}

	/**
	 * @throws Exception
	 */
	public void testAsList() throws Exception {
		List list = Arrays.asList(new String[]{"A", "BB", "CCC"});
		List asList = LzList.asList(list.iterator());
		assertTrue(asList.toString().equals("[A, BB, CCC]"));
		
		Vector vector = new Vector(list);
		List asList2 = LzList.asList(vector.elements());
		assertTrue(asList2.toString().equals("[A, BB, CCC]"));
	}

	/**
	 * @throws Exception
	 */
	public void testEquals() throws Exception {
		List list1 = Arrays.asList(new String[]{"A", "B", "C"});
		List list2 = Arrays.asList(new String[]{"A", "B", "C"});
		assertTrue(new LzList(list1).equals(list2));

		List list3 = Arrays.asList(new String[]{"A", null, null, "C"});
		List list4 = Arrays.asList(new String[]{"A", null, "B", null});
		assertTrue(!new LzList(list3).equals(list4));
	}
	
	/**
	 * @throws Exception
	 */
	public void testEqualsOnSort() throws Exception {
		List list1 = Arrays.asList(new String[]{"A", "B", "C"});
		List list2 = Arrays.asList(new String[]{"C", "A", "B"});
		assertTrue(new LzList(list1).equalsOnSort(list2));
	}

	/**
	 * @throws Exception
	 */
	public void testToString() throws Exception {
		assertTrue(new LzList(new String[]{"a", null, "c"}).toString().equals("[a, null, c]"));
	}
	
	/**
	 * @throws Exception
	 */
	public void testGrep() throws Exception {
		List list = Arrays.asList(new String[]{"foo", "bar", "hoge", null});;
		assertTrue(new LzList(list).grep("o").toString().equals("[foo, hoge]"));
	}
	
	/**
	 * @throws Exception
	 */
	public void testUngrep() throws Exception {
		List list = Arrays.asList(new String[]{"foo", "bar", "hoge", null});;
		assertTrue(new LzList(list).ungrep("o").toString().equals("[bar]"));
	}
	
	/**
	 * @throws Exception
	 */
	public void testLzListClosure() throws Exception {
		List list1 = Arrays.asList(new String[]{"AAA", "ABB", "CCC"});
		final String var = "A";
		LzList grep = new LzList(list1).forEach(new LzListClosure(){
			public boolean process(int i, int len, Object obj) {
				String str = (String)obj;
				return str.startsWith(var);
			}
		});
		assertTrue(grep.equals("[AAA, ABB]"));
	}

	private class FooBean {
		private String name = "null";
		public String getName() { return name; }
		void setName(String arg) { name = arg; }
		public String toString() { return "name="+name; }
	}
	
	/**
	 * @throws Exception
	 */
	public void testLzListClosure2() throws Exception {
		List fooList = Arrays.asList(new FooBean[]{ new FooBean(), new FooBean(), new FooBean() });
		List resultList = new LzList(fooList).forEach(new LzListClosure(){
			public boolean process(int i, int len, Object obj) {
				FooBean foo = (FooBean)obj;
				foo.setName("Mr."+(i+1));
				return true;
			}
		}).list();
		StringBuffer buff = new StringBuffer();
		int len = resultList.size();
		for (int i = 0; i < len; i++) {
			buff.append(fooList.get(i).toString());
			if (!(i+1==len)) buff.append(", ");
		}
		assertTrue(new String(buff).equals("name=Mr.1, name=Mr.2, name=Mr.3"));
	}

}
