package editortrees;

import static org.junit.Assert.*;

import org.junit.Before;
import org.junit.Test;

public class EditTreeTest {

	static int points = 0;

	// Feel free to use these strings in your test cases, or not.

	static String s1 = "short string",
			s2 = "a moderately short string",
			s3 = "This string is not as short as the others",
			s4 = "This is a great, big, juicy, longer-than-the-others, string",
			s5 = "You can't always get the strings you want, "
					+ "but if you try sometimes, you just might find you get the strings you need.";

	/**
	 * The variables whose first two digits are your team number are available
	 * for your team's test cases to use. If you want to intiialize them once
	 * and for all instead of in individual test cases, put that code in setUpXY,
	 * where XY is your team number. You may use other variables, of course, but
	 * they should be local to your methods.
	 */
	EditTree t110, t111, t112, t113, t114, t115, t116, t117, t118, t119;
	EditTree t120, t121, t122, t123, t124, t125, t126, t127, t128, t129;
	EditTree t130, t131, t132, t133, t134, t135, t136, t137, t138, t139;
	EditTree t140, t141, t142, t143, t144, t145, t146, t147, t148, t149;
	EditTree t150, t151, t152, t153, t154, t155, t156, t157, t158, t159;
	EditTree t160, t161, t162, t163, t164, t165, t166, t167, t168, t169;
	EditTree t210, t211, t212, t213, t214, t215, t216, t217, t218, t219;
	EditTree t220, t221, t222, t223, t224, t225, t226, t227, t228, t229;
	EditTree t230, t231, t232, t233, t234, t235, t236, t237, t238, t239;
	EditTree t240, t241, t242, t243, t244, t245, t246, t247, t248, t249;
	EditTree t250, t251, t252, t253, t254, t255, t256, t257, t258, t259;
	EditTree t260, t261, t262, t263, t264, t265, t266, t267, t268, t269;
	EditTree ti0, ti1, ti2, ti3, ti4, ti5, ti6, ti7, ti8, ti9;

	// Do not modify this method

	@Before
	public void setUp() throws Exception {
		setUpInstructors();
		setUp11();
		setUp12();
		setUp13();
		setUp14();
		setUp15();
		setUp16();
		setUp21();
		setUp22();
		setUp23();
		setUp24();
		setUp25();
		setUp26();
	}

	/*
	 * trees to test: null tree just the root just left just right both
	 * directions s1 s2 s3 s4 "hlo" for testing add(e, 2) and add(l,4)
	 */
	public void setUpInstructors() throws Exception {

	}

	public void setUp11() throws Exception {

	}

	public void setUp12() throws Exception {

	}

	public void setUp13() throws Exception {

	}

	public void setUp14() throws Exception {

	}

	public void setUp15() throws Exception {

	}

	public void setUp16() throws Exception {

	}

	public void setUp21() throws Exception {

	}

	public void setUp22() throws Exception {
		// Null Tree
		t220 = new EditTree();
		// Just root, has character a. Tests the one character constructor
		t221 = new EditTree('a');
		// Should set up a, then b to the rights. Tests the string constructor.
		t222 = new EditTree("ab");
		// Both sides. Should be "abc" in order. Tests the string constructor
		t223 = new EditTree("abc");
		// Set up tree for s1. Tests the string constructor
		t224 = new EditTree(s1);
		// Set up tree for s2. Tests the string constructor
		t225 = new EditTree(s2);
		// Set up tree for s3. Tests the string constructor
		t226 = new EditTree(s3);
		// Set up tree for s4. Tests the string constructor.
		t227 = new EditTree(s4);
		// Set up tree for "hlo". Will be used to test add(c,pos)
		t228 = new EditTree("hlo");
		// Set up tree for "test tree". Set up tests String constructor.
		t229 = new EditTree("Test Tree");

		/*Just display the trees to see if they constructed properly.  Will be commented out at final commit time*/
//		DisplayTree.display(t220);
//
//		DisplayTree.display(t221);
//
//		DisplayTree.display(t222);
//
//		DisplayTree.display(t223);
//
//		DisplayTree.display(t224);
//
//		DisplayTree.display(t225);
//
//		DisplayTree.display(t226);
//
//		DisplayTree.display(t227);
//
//		DisplayTree.display(t228);
//
//		DisplayTree.display(t229);
}

	public void setUp23() throws Exception {

	}

	public void setUp24() throws Exception {

	}

	public void setUp25() throws Exception {

	}

	public void setUp26() throws Exception {

	}

	// The name of each of your team's tests should end with an underscore
	// followed by your team number,
	// for example, testSize3_13 if you are on team 13.

	// Make sure that each of your tests has a timeout.
	// The timeout should be 1 or 2 seconds unless your
	// test involves VERY complicated operations.

	// Each of your tests should be worth one point.

	// A sample test to remind you of the format:

	@Test
	// one second
	public void testSize3_i() { // i is for instructor
		ti3 = new EditTree(s1);
		DisplayTree.display(ti3);
		assertEquals(12, ti3.size());
		points += 1; // only incremented if test passes.
	}
	
	/*Tests sizes on all the trees.*/
	@Test(timeout = 1000)
	public void testSize_22() {
		assertEquals(0, t220.size());
		assertEquals(1, t221.size());
		assertEquals(2, t222.size());
		assertEquals(3, t223.size());
		assertEquals(s1.length(), t224.size());
		assertEquals(s2.length(), t225.size());
		assertEquals(s3.length(), t226.size());
		assertEquals(s4.length(), t227.size());
		assertEquals(3, t228.size());
		assertEquals(9, t229.size());
		points += 1; // only incremented if test passes.
	}

	/*
	 * Tests add position on "hlo" by adding the e and the l to make the tree
	 * "hello". Should demonstrate a push right and a add right, which are the
	 * two ways we add at a position
	 */
	@Test(timeout = 1000)
	public void testAddPosition_22() {
		t228.add('e', 1);
		t228.add('l', 3);
		assertEquals("hello", t228.toString());
		points += 1; // only incremented if test passes.
	}
	
	/*Tests delete by restoring t228 ("hlo") to its initial state.  Tests delete on other trees as well.*/
	//TODO:  Work on this one
	@Test(timeout = 1000)
	public void testAddDelete_22(){
		t228.add('e', 1);
		t228.add('l', 3);
		t228.delete(3);
		t228.delete(1);
		assertEquals("hlo", t228.toString());
		points += 1; // only incremented if test passes.
	}
	
	//Tests that a deletion on a null tree throws an exception
	@Test(expected = IndexOutOfBoundsException.class)
	public void testNullDelete_22(){
		t220.delete(1);
		points += 1; // only incremented if test passes.
	}
	
	//Tests that out of bounds deletes yell at you properly
	@Test (expected = IndexOutOfBoundsException.class)
	public void testOutOfBoundsDelete_22(){
		t227.delete(s4.length() + 1);
		points += 1; // only incremented if test passes.
	}
	
	
	//Tests duplicate by duplicating th	posen calling .equals() on the root node of each
	@Test
	public void testDuplicateConstructor_22(){
		//Test tree with stuff in it
		EditTree duplicate = new EditTree(t227);
		assertTrue(duplicate.equals(t227));
		//Test null tree
		EditTree duplicate2 = new EditTree(t220);
		assertTrue(duplicate2.equals(t220));
		points += 1; // only incremented if test passes.
	}
	
	//I just wanted to see some green on the test screen.
	@Test
	public void realityCheck_22(){
		assertTrue(true);
	}
	
	@Test(timeout = 1000)
	public void testDelete_22(){
		assertEquals('a',t221.delete(0));
		assertEquals("",t221.toString());
		assertEquals('b',t222.delete(1));
		assertEquals("a",t222.toString());
		assertEquals('c',t223.delete(2));
		assertEquals("ab",t223.toString());
		assertEquals('r',t224.delete(8));
		assertEquals("short sting",t224.toString());
		assertEquals('d',t225.delete(4));
		assertEquals("a moerately short string",t225.toString());
		assertEquals('o',t226.delete(16));
		assertEquals("This string is nt as short as the others",t226.toString());
		assertEquals(',',t227.delete(15));
		assertEquals("This is a great big, juicy, longer-than-the-others, string",t227.toString());
		points += 1; // only incremented if test passes.
	}
	
	@Test(timeout = 1000)
	public void testHeight_22(){
		assertEquals(-1, t220.height());
		assertEquals( 0, t221.height());
		assertEquals( 1, t222.height());
		assertEquals( 1, t223.height());
		assertEquals( 3, t224.height());
		assertEquals( 4, t225.height());
		assertEquals( 4, t226.height());
		assertEquals( 5, t227.height());
		assertEquals( 3, t229.height());
		points += 1; // only incremented if test passes.
	}
	
	@Test(timeout = 1000)
	public void testGet_22(){
		assertEquals('a',t221.get(0));
		assertEquals('b',t222.get(1));
		assertEquals('b',t223.get(1));
		assertEquals('o',t224.get(2));
		assertEquals('e',t225.get(9));
		assertEquals(' ',t226.get(21));
		assertEquals('g',t227.get(19));
		points += 1; // only incremented if test passes.
	}

	
	@Test(timeout = 1000)
	public void testGet2_22(){
		assertEquals("ab",t222.get(0,2));
		assertEquals("bc",t223.get(1,2));
		assertEquals("ort",t224.get(2,3));
		assertEquals("ode",t225.get(7,3));
		assertEquals(" as short as ",t226.get(21,13));
		assertEquals("",t227.get(19,0));
		points += 1; // only incremented if test passes.
	}
	
	@Test(timeout = 1000)
	public void testCheckRanks_22(){
		assertTrue(t220.checkRanks());
		assertTrue(t221.checkRanks());
		assertTrue(t222.checkRanks());
		assertTrue(t223.checkRanks());
		assertTrue(t224.checkRanks());
		assertTrue(t225.checkRanks());
		assertTrue(t226.checkRanks());
		assertTrue(t227.checkRanks());
		assertTrue(t228.checkRanks());
		assertTrue(t229.checkRanks());
		points += 1; // only incremented if test passes.
	}

	
	//Check actual lengths on this one.
	@Test(timeout = 1000)
	public void testLengthDelete_22(){
		assertEquals(new EditTree("strin"),t224.delete(7, 5));
		points++;
	}
	
	@Test(timeout = 1000, expected = IndexOutOfBoundsException.class)
	public void testNullLengthDelete_22(){
		t220.delete(2,2);
		points++;
	}

	@Test(timeout = 1000)
	public void testisHeightBalanced_22(){
		assertTrue(t220.isHeightBalanced());
		assertTrue(t221.isHeightBalanced());
		assertTrue(t222.isHeightBalanced());
		assertTrue(t223.isHeightBalanced());
		assertTrue(t224.isHeightBalanced());
		assertTrue(t225.isHeightBalanced());
		assertTrue(t226.isHeightBalanced());
		assertTrue(t227.isHeightBalanced());
		assertTrue(t228.isHeightBalanced());
		assertTrue(t229.isHeightBalanced());
		points += 1; // only incremented if test passes.

	}

	@Test(timeout = 1000)
	public void testToString_22(){
		assertEquals("", t220.toString());
		assertEquals("a", t221.toString());
		assertEquals("ab", t222.toString());
		assertEquals("abc", t223.toString());
		assertEquals(s1, t224.toString());
		assertEquals(s2, t225.toString());
		assertEquals(s3, t226.toString());
		assertEquals(s4, t227.toString());
		assertEquals("hlo", t228.toString());
		assertEquals(s5, new EditTree(s5));
		points++;
	}
	
	@Test (timeout = 1000)
	public void testConcatenate_22(){
		t220.concatenate(t221);
		assertEquals("a",t220.toString());
		t224.concatenate(t225);
		assertEquals(s1+s2,t224.toString());
		t224.concatenate(t226);
		assertEquals(s1+s2+s3, t224.toString());
		t224.concatenate(t227);
		assertEquals(s1+s2+s3+s4,t224.toString());
		points++;
	}
	
	@Test (timeout = 1000, expected = IndexOutOfBoundsException.class)
	public void testOutofBoundsSplit_22(){
		EditTree fail = t221.split(2);
		points++;
	}
	
	@Test (timeout = 1000)
	public void testSplit_22(){
		assertEquals(s1.substring(5),t224.split(5).toString());
		assertEquals(s2.substring(10),t225.split(10).toString());
		assertEquals(s3.substring(15),t226.split(15).toString());
		assertEquals(s4.substring(20),t227.split(20).toString());
		assertEquals(s5.substring(30),new EditTree(s5).split(30).toString());
		points++;
	}
	
	@Test(timeout = 3000)
	public void testFind_22(){
		assertEquals(-1,t220.find("Secrets of Life"));
		assertEquals(0,t221.find("a"));
		assertEquals(1,t222.find("b"));
		assertEquals(s1.indexOf("string"),t224.find("string"));
		assertEquals(s2.indexOf("moderate"),t225.find("moderate"));
		assertEquals(s2.indexOf("moderate",10),t225.find("moderate",10));
		assertEquals(s3.indexOf("short"),t226.find("short"));
		assertEquals(s4.indexOf("is"),t227.find("is"));
		assertEquals(s4.indexOf("is",4),t227.find("is",4));
		points++;
	}
	
}