package junkutil.set;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

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

/**
 * LzMapTestをテストする。
 */
public class LzMapTest extends TestCase {
	private LzMap test1 = new LzMap(new String[]{
			"a", "1",
			"b", "2",
			"c", "3",
	});
	private LzMap test2 = new LzMap(new String[]{
			"b", "4",
			"c", "5",
			"d", "6",
	});
	private LzMap test3 = new LzMap(new String[]{
			"b", "2",
			"a", "1",
			"c", "3",
	});
	private LzMap test4 = null;
	private LzMap test5 = new LzMap(new String[]{
			"a", "1",
			"b", null,
			"c", "3",
			"d", null,
	});
	private LzMap test6 = new LzMap(new String[]{
			"a", "1",
			"b", "2",
			"c", "3",
			"d", null,
	});
	
	/**
	 * コンストラクタ
	 * @param name
	 */
	public LzMapTest(String name) {
		super(name);
	}

	/**
	 * @return
	 */
	public static Test suite() {
		TestSuite test = new TestSuite("LzMapTest");
		test.addTest(new TestSuite(LzMapTest.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 testKeys() throws Exception {
		assertTrue(new LzList(test1.keys()).sortAsc().equals("[a, b, c]"));
	}
	
	/**
	 * @throws Exception
	 */
	public void testSortedKeys() throws Exception {
		assertTrue(new LzList(test1.sortedKeys()).equals("[a, b, c]"));
		assertTrue(new LzList(test1.sortedKeys(new Comparator(){
			public int compare(Object o1, Object o2) {
				String s1 = (String)o1;
				String s2 = (String)o2;
				return s2.compareTo(s1);
			}
		})).equals("[c, b, a]"));
	}
	
	/**
	 * @throws Exception
	 */
	public void testValues() throws Exception {
		assertTrue(new LzList(test1.values()).sortAsc().equals("[1, 2, 3]"));
	}
	
	/**
	 * @throws Exception
	 */
	public void testOrLeft() throws Exception {
		assertTrue(test1.orLeft(test2.map()).equals("{a=1, b=2, c=3, d=6}"));
	}
	
	/**
	 * @throws Exception
	 */
	public void testMarge() throws Exception {
		assertTrue(test1.marge(test2.map()).equals("{a=1, b=4, c=5, d=6}"));
	}
	
	/**
	 * @throws Exception
	 */
	public void testAndLeft() throws Exception {
		assertTrue(test1.andLeft(test2.map()).equals("{b=2, c=3}"));
	}
	
	/**
	 * @throws Exception
	 */
	public void testAndRight() throws Exception {
		assertTrue(test1.andRight(test2.map()).equals("{b=4, c=5}"));
	}
	
	/**
	 * @throws Exception
	 */
	public void testSet() throws Exception {
		assertTrue(test1.set(test2.map()).equals("{a=1, b=4, c=5}"));
	}

	/**
	 * @throws Exception
	 */
	public void testNotNull() throws Exception {
		assertTrue(test5.notNull().equals("{a=1, c=3}"));
	}

	/**
	 * @throws Exception
	 */
	public void testEquals() throws Exception {
		assertTrue(!test1.equals(test2.map()));
		assertTrue(test1.equals(test3.map()));
		assertTrue(!test5.equals(test6.map()));
	}

	/**
	 * @throws Exception
	 */
	public void testToString() throws Exception {
		assertTrue(test1.toString().equals("{a=1, b=2, c=3}"));
	}

	/**
	 * @throws Exception
	 */
	public void testProperties() throws Exception {
		test4 = new LzMap(System.getProperties());
		assertTrue(true);
	}
	
	/**
	 * @throws Exceptoin
	 */
	public void testKeyGrep() throws Exception {
		assertTrue(test1.keyGrep("a|b").equals("{a=1, b=2}"));
		assertTrue(test1.keyUngrep("b|c").equals("{a=1}"));
	}

	/**
	 * @throws Exception
	 */
	public void testLzMapClosure() throws Exception {
		final String var1 = "a";
		final String var2 = "b";
		
		LzMap grep1 = test1.forEach(new LzMapClosure(){
			public boolean process(Object key, Object value) {
				String keyStr = (String)key;
				return keyStr.startsWith(var1) || keyStr.startsWith(var2);
			}
		});
		assertTrue(grep1.equals("{a=1, b=2}"));
		
		LzMap grep2 = test1.forEach(test1.keys(), new LzMapClosure(){
			public boolean process(Object key, Object value) {
				String keyStr = (String)key;
				return keyStr.startsWith(var1) || keyStr.startsWith(var2);
			}
		});
		assertTrue(grep2.equals("{a=1, b=2}"));
	}
	
	/**
	 * @throws Exceptoin
	 */
	public void testSubset() throws Exception {
		assertTrue(test1.subset(new String[]{"a","b"}).equals("{a=1, b=2}"));
		assertTrue(test1.subset(new String[]{"b","c","d"}).equals("{b=2, c=3, d=null}"));
		assertTrue(test1.subset(Arrays.asList(new String[]{"a","b"})).equals("{a=1, b=2}"));
		assertTrue(test1.subset(Arrays.asList(new String[]{"b","c","d"})).equals("{b=2, c=3, d=null}"));
	}
}
