package test;
import org.junit.*;
import static org.junit.Assert.*;

public class StackDemo3Tester {
	private StackDemo3<String> testStack;
	private String elt1 = "1", elt2 = "2", elt3 = "3";
	
	@Before public void setUp() {
		testStack = new StackDemo3<String>();
	}
	
	@Test public void testEmpty1() {
		assertTrue(testStack.empty());
	}
	
	public void push3() {
		testStack.push(elt1);
		testStack.push(elt2);
		testStack.push(elt3);
	}
	
	@Test(expected = ArrayIndexOutOfBoundsException.class) public void testPopEmpty() {
		testStack.pop();
	}
	
	@Test(expected = ArrayIndexOutOfBoundsException.class) public void testTopEmpty() {
		testStack.top();
	}	
	
	@Test public void testPush() {
		String element = "hello";
		testStack.push(element);
		assertTrue(testStack.top() == element && testStack.size() == 1);
	}
	
	@Test public void testNth1() {
		push3();
		assertTrue(testStack.nthFromTop(0) == elt3);
		assertTrue(testStack.nthFromTop(1) == elt2);
		assertTrue(testStack.nthFromTop(2) == elt1);
	}
	
	@Test(expected = IndexOutOfBoundsException.class) public void testNth2() {
		testStack.nthFromTop(-1);
	}
	
	@Test(expected = ArrayIndexOutOfBoundsException.class) public void testNth3() {
		push3();
		testStack.nthFromTop(testStack.size());
	}
	
	@Test public void testTop() {
		push3();
		assertTrue(testStack.top() == elt3);
	}
	
	public void testPopStep() {
		String oldNth1 = testStack.nthFromTop(1);
		int oldSize = testStack.size();
		testStack.pop();		
		assertTrue(testStack.top() == oldNth1 && testStack.size() == oldSize - 1);
	}
	
	@Test public void testPop1() {
		push3();
		testPopStep();
		testPopStep();
	}
	
	@Test public void testPop2() {
		push3();
		testStack.pop();
		testStack.pop();
		testStack.pop();
		assertTrue(testStack.empty());
	}
}
