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 initialize 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 {

		try {

			setUpInstructors();

		} catch (Exception e) {

			System.out.println("Error in setUpInstructors:");

			e.printStackTrace();

		}

		try {

			setUp11();

		} catch (Exception e) {

			System.out.println("Error in setUp11:");

			e.printStackTrace();

		}

		try {

			setUp12();

		} catch (Exception e) {

			System.out.println("Error in setUp12:");

			e.printStackTrace();

		}

		try {

			setUp13();

		} catch (Exception e) {

			System.out.println("Error in setUp13:");

			e.printStackTrace();

		}

		try {

			setUp14();

		} catch (Exception e) {

			System.out.println("Error in setUp14:");

			e.printStackTrace();

		}

		try {

			setUp15();

		} catch (Exception e) {

			System.out.println("Error in setUp15:");

			e.printStackTrace();

		}

		try {

			setUp16();

		} catch (Exception e) {

			System.out.println("Error in setUp16:");

			e.printStackTrace();

		}

		try {

			setUp21();

		} catch (Exception e) {

			System.out.println("Error in setUp21:");

			e.printStackTrace();

		}

		try {

			setUp22();

		} catch (Exception e) {

			System.out.println("Error in setUp22:");

			e.printStackTrace();

		}

		try {

			setUp23();

		} catch (Exception e) {

			System.out.println("Error in setUp23:");

			e.printStackTrace();

		}

		try {

			setUp24();

		} catch (Exception e) {

			System.out.println("Error in setUp24:");

			e.printStackTrace();

		}

		try {

			setUp25();

		} catch (Exception e) {

			System.out.println("Error in setUp25:");

			e.printStackTrace();

		}

		try {

			setUp26();

		} catch (Exception e) {

			System.out.println("Error in setUp26:");

			e.printStackTrace();

		}

	}



	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 {

		t210 = new EditTree(s1);

		t211 = new EditTree(s2);

		t212 = new EditTree(s3);

		t213 = new EditTree(s4);

		t214 = new EditTree(s5);

	}



	public void setUp22() throws Exception {



	}



	public void setUp23() throws Exception {



	}



	public void setUp24() throws Exception {



	}



	public void setUp25() throws Exception {



	}



	public void setUp26() throws Exception {



	}



	@Test(timeout = 2000)

	// Tests constructing a EditTree from an EditTree

	public void testConstructor4_21() {

		assertEquals(t210.toString(), new EditTree(t210).toString());

		assertEquals(t211.toString(), new EditTree(t211).toString());

		assertEquals(t212.toString(), new EditTree(t212).toString());

		assertEquals(t213.toString(), new EditTree(t213).toString());

		assertEquals(t214.toString(), new EditTree(t214).toString());



		assertFalse(t210.equals(new EditTree(t210)));

		assertFalse(t211.equals(new EditTree(t211)));

		assertFalse(t212.equals(new EditTree(t212)));

		assertFalse(t213.equals(new EditTree(t213)));

		assertFalse(t214.equals(new EditTree(t214)));

		points += 1;

	}



	@Test(timeout = 2000)

	public void testToString_21() {

		assertEquals(s1, t210.toString());

		assertEquals(s2, t211.toString());

		assertEquals(s3, t212.toString());

		assertEquals(s4, t213.toString());

		assertEquals(s5, t214.toString());

		points += 1;

	}



	@Test(timeout = 2000)

	// Tests the add method for adding a character at the end of a string. (The

	// add method with only one parameter)

	public void testAdd_21() {

		t215 = new EditTree("short strin");

		t215.add('g');

		assertEquals(s1, t215.toString());

		t216 = new EditTree("a moderately short strin");

		t216.add('g');

		assertEquals(s2, t216.toString());

		t217 = new EditTree("This string is not as short as the other");

		t217.add('s');

		assertEquals(s3, t217.toString());

		t218 = new EditTree(

				"This is a great, big, juicy, longer-than-the-others, strin");

		t218.add('g');

		assertEquals(s4, t218.toString());

		t219 = new EditTree(

				"You can't always get the strings you want, "

						+ "but if you try sometimes, you just might find you get the strings you need");

		t219.add('.');

		assertEquals(s5, t219.toString());



		// Tests repetitive addition

		t211 = new EditTree("");

		for (int i = 0; i < s3.length(); i++)

			t211.add(s3.charAt(i));

		assertEquals(s3, t211.toString());



		points += 1;

	}



	@Test(timeout = 2000)

	// Tests the add method for inserting characters at places besides the end.

	// (The add method with two parameters)

	public void testAdd2_21() {

		t215 = new EditTree("shortstring");

		t215.add(' ', 4);

		assertEquals(s1, t215.toString());

		t216 = new EditTree("hort string");

		t216.add('s', -1);

		assertEquals(s1, t216.toString());

		t217 = new EditTree(" moderately short string");

		t217.add('a', -1);

		assertEquals(s2, t217.toString());

		t218 = new EditTree("a" + "moderately short string");

		t218.add(' ', 0);

		assertEquals(s2, t218.toString());

		t219 = new EditTree("");



		// Tests repetitive adding.

		for (int i = s3.length() - 1; i >= 0; i--)

			t219.add(s3.charAt(i), 0);

		assertEquals(s3, t219.toString());



		points += 1;

	}



	@Test(timeout = 2000)

	// Tests that the add method throws a correct error if out of bounds

	public void testAddException_21() throws Exception {

		try {

			t210.add('x', 25);

			fail("Add method did not throw IndexOutOfBoundsException.");

		} catch (IndexOutOfBoundsException exception) {

			points += 1;

		}

	}



	@Test(timeout = 2000)

	// Tests the delete method that removes a single character from the tree

	public void testDelete_21() {

		t210.delete(5);

		assertEquals("shortstring", t210.toString());

		t211.delete(1);

		assertEquals("amoderately short string", t211.toString());

		t212.delete(0);

		assertEquals("his string is not as short as the others", t212

				.toString());



		// Tests repetitive deletion

		while (t210.size() > 0) {

			t210.delete(0);

		}

		assertEquals("", t210.toString());



		points += 1;

	}



	@Test(timeout = 2000)

	// Tests the delete method that removes a substring from the tree

	public void testDelete2_21() {

		t210.delete(5, t210.size() - 1);

		assertEquals("short", t210.toString());

		t210.delete(0, t210.size());

		assertEquals("", t210.toString());

		t211.delete(0, 13);

		assertEquals(s1, t211.toString());

		t211.delete(1, t211.size());

		assertEquals("a", t211.toString());



		points += 1;

	}



	@Test(timeout = 2000)

	// Tests that the delete method throws a correct error if out of bounds

	public void testDeleteException_21() throws Exception {

		try {

			t210.delete(25);

			fail("Delete method did not throw IndexOutOfBoundsException.");

		} catch (IndexOutOfBoundsException exception) {

			points += 1;

		}

	}



	@Test(timeout = 2000)

	// Tests that the second delete method throws the proper error

	public void testDeleteException2_21() throws Exception {

		try {

			t210.delete(2, 25);

			fail("Delete method did not throw IndexOutOfBoundsException.");

		} catch (IndexOutOfBoundsException exception) {

			points += 1;

		}

	}



	@Test(timeout = 2000)

	// Tests the concatenate method that appends a string-tree.

	public void testConcatenate_21() {

		t215 = new EditTree("string");

		t216 = new EditTree("short ");

		t216.concatenate(t215);

		assertEquals(s1, t216.toString());

		assertEquals(0, t215.size());

		t217 = new EditTree("st");

		t218 = new EditTree("short ");

		t219 = new EditTree("ring");

		t217.concatenate(t219);

		assertEquals("string", t217.toString());

		t218.concatenate(t217);

		assertEquals(s1, t218.toString());

		assertEquals(0, t217.size());

		assertEquals(0, t219.size());



		points += 1;

	}



	@Test(timeout = 2000)

	// Tests that the concatenate method throws the correct exception

	public void testConcatenateException_21() throws Exception {

		try {

			t210.concatenate(t210);

			fail("Concatenate method did not throw IllegalArgumentException.");

		} catch (IllegalArgumentException exception) {

			points += 1;

		}

	}



	@Test(timeout = 2000)

	public void testFind_21() {

		// Tests the find method that finds the first instance of a substring

		assertEquals(s1.indexOf(" st"), t210.find(" st"));

		assertEquals(s1.indexOf("short"), t210.find("short"));

		assertEquals(s1.indexOf("hi"), t210.find("hi"));

		assertEquals(s2.indexOf("a"), t211.find("a"));

		assertEquals(s2.indexOf("er"), t211.find("er"));

		assertEquals(s2.indexOf("ello"), t211.find("ello"));

		assertEquals(s3.indexOf(" is "), t212.find(" is "));

		assertEquals(s3.indexOf("hello"), t212.find("hello"));



		points += 1;

	}



	@Test(timeout = 2000)

	public void testFind2_21() {

		// Tests the find method that finds the first instance of a substring

		// after a given starting position

		assertEquals(s1.indexOf(" st", 4), t210.find(" st", 4));

		assertEquals(s1.indexOf("hort", 0), t210.find("hort", 0));

		assertEquals(s1.indexOf("hi", 2), t210.find("hi", 2));

		assertEquals(s2.indexOf("moderately", 0), t211.find("moderately", 0));

		assertEquals(s2.indexOf("short", 7), t211.find("short", 7));

		assertEquals(s2.indexOf("moderately", 5), t211.find("moderately", 5));

		assertEquals(s2.indexOf("foo", 0), t211.find("foo", 0));



		points += 1;

	}



	@Test(timeout = 2000)

	// Tests the split method that cuts the tree into two subtrees at a given

	// index.

	public void testSplit_21() {

		t215 = t210.split(5);

		assertEquals("short ", t210.toString());

		assertEquals("string", t215.toString());

		t211 = t210.split(0);

		assertEquals("", t210.toString());

		assertEquals("short ", t211);

		t212 = t211.split(6);

		assertEquals("short ", t211);

		assertEquals("", t212);



		points += 1;

	}



	@Test(timeout = 2000)

	// Tests the split method throws the proper exception

	public void testSplitException_21() {

		try {

			t210.split(-1);

			fail("Split method did not throw IndexOutOfBoundsException.");

		} catch (IndexOutOfBoundsException exception) {

			points += 1;

		}

	}



	@Test(timeout = 2000)

	// Tests the split method throws the proper exception

	public void testSplitException2_21() {

		try {

			t210.split(25);

			fail("Split method did not throw IndexOutOfBoundsException.");

		} catch (IndexOutOfBoundsException exception) {

			points += 1;

		}

	}



	@Test(timeout = 2000)

	// Tests that the get method actually returns the Node at a given position

	public void testGet_21() {

		// i goes from 0 to the length of the shortest string

		for (int i = 0; i < Math.min(s1.length(), Math.min(s2.length(), Math

				.min(s3.length(), Math.min(s4.length(), s5.length())))); i++) {



			assertEquals(s1.charAt(i), t210.get(i).element);

			assertEquals(s2.charAt(i), t211.get(i).element);

			assertEquals(s3.charAt(i), t212.get(i).element);

			assertEquals(s4.charAt(i), t213.get(i).element);

			assertEquals(s5.charAt(i), t214.get(i).element);

		}

		points += 1;

	}



	@Test(timeout = 2000)

	// Tests that the get method throws an exception when index is out of bounds

	public void testGetException_21() {

		try {

			t210.get(25);

			fail("Get method did not throw IndexOutOfBoundsException.");

		} catch (IndexOutOfBoundsException exception) {

			points += 1;

		}

	}



	@Test(timeout = 2000)

	// Tests that the get method throws an exception when length is out of

	// bounds

	public void testGetException2_21() {

		try {

			t210.get(2, 25);

			fail("Get method did not throw IndexOutOfBoundsException.");

		} catch (IndexOutOfBoundsException exception) {

			points += 1;

		}

	}



	@Test(timeout = 2000)

	// Tests the height of the tree

	public void testHeight_21() {

		t215 = new EditTree("short strin");

		assertEquals(3, t215.height());

		assertEquals(3, t210.height());

		assertEquals(4, t211.height());

		assertEquals(5, t212.height());

		assertEquals(5, t213.height());

		assertEquals(6, t214.height());

		t216 = new EditTree("");

		t217 = new EditTree('a');

		t218 = new EditTree("s");

		t219 = new EditTree("sh");

		t210 = new EditTree("sho");

		t211 = new EditTree("shor");

		t212 = new EditTree("short");



		assertEquals(-1, t216.height());

		assertEquals(0, t217.height());

		assertEquals(0, t218.height());

		assertEquals(1, t219.height());

		assertEquals(1, t210.height());

		assertEquals(2, t211.height());

		assertEquals(2, t212.height());



		points += 1;



	}



	@Test(timeout = 2000)

	// Tests that the tree automatically rotates when an element is added

	public void testRotate_21() {

		t215 = new EditTree(new Node('a'));

		t215.add('b');

		t215.add('c');

		assertEquals('b', t215.getRoot().element);

		t215.add('d');

		assertEquals('b', t215.getRoot().element);

		t215.add('e');

		assertEquals('b', t215.getRoot().element);

		t215.add('f');

		assertEquals('d', t215.getRoot().element);

		t215.add('g');

		assertEquals('d', t215.getRoot().element);

		points += 1;

	}



	@Test(timeout = 2000)

	public void testRanks_21() {

		// The rank of a node is the size of its left subtree

		assertEquals(t210.getRoot().left.size(), t210.getRoot().rank);

		assertEquals(t211.getRoot().left.size(), t211.getRoot().rank);

		assertEquals(t212.getRoot().left.size(), t212.getRoot().rank);

		assertEquals(t213.getRoot().left.size(), t213.getRoot().rank);

		assertEquals(t214.getRoot().left.size(), t214.getRoot().rank);



		// Asserts rank after a node has been added.

		t210.add('x', -1);

		assertEquals(t210.getRoot().left.size(), t210.getRoot().rank);



		// Asserts rank after many nodes have been added.

		for (int i = 1; i < t210.size(); i += 2) {

			t210.add('x', -1);

		}

		assertEquals(t210.getRoot().left.size(), t210.getRoot().rank);

		points += 1;

	}



	@Test(timeout = 2000)

	// Tests the check Ranks method, which asserts if the tree has correct

	// ranks.

	public void testCheckRanks_21() {

		assertTrue(t210.checkRanks());

		assertTrue(t211.checkRanks());

		assertTrue(t212.checkRanks());

		assertTrue(t213.checkRanks());

		assertTrue(t214.checkRanks());



		points += 1;

	}



	@Test(timeout = 2000)

	// Tests the isHeightBalanced method, which asserts if the tree is height

	// balanced.

	public void testIsHeightBalanced_21() {

		assertTrue(t210.isHeightBalanced());

		assertTrue(t211.isHeightBalanced());

		assertTrue(t212.isHeightBalanced());

		assertTrue(t213.isHeightBalanced());

		assertTrue(t214.isHeightBalanced());

	}



	@Test(timeout = 2000)

	// Tests if changes to a tree keeps the tree heightBalanced. Most of the

	// previous methods must work in order for this test to pass.

	public void testIsHeightBalanced2_21() {

		t210 = new EditTree();

		for (int i = 0; i < s2.length(); i++)

			t210.add(s2.charAt(i));



		t211.concatenate(t212);

		t213.split(s4.length() / 2);

		t214.delete(4, 25);



		assertTrue(t210.isHeightBalanced());

		assertTrue(t211.isHeightBalanced());

		assertTrue(t213.isHeightBalanced());

		assertTrue(t214.isHeightBalanced());



		points += 1;

	}



	// 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(timeout = 1000)

	// one second

	public void testSize3_i() { // i is for instructor

		ti3 = new EditTree(s1);

		assertEquals(12, ti3.size());



		points += 1; // only incremented if test passes.

	}



}