import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.startsWith;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

public class NumbersTest {

	private Numbers numbers;

	@Before
	public void setUp(){
		numbers = new NumbersImpl();
	}
	
	@Test
	public void testIsPrime() {
		assertEquals("Failure - 1 is a prime number.", true, numbers.isPrime(1) );
		assertEquals("Failure - 2 is not a prime number.", false, numbers.isPrime(2) );
		assertEquals("Failure - 3 is a prime number.", true, numbers.isPrime(3) );
		assertEquals("Failure - 4 is not a prime number.", false, numbers.isPrime(4) );
		assertEquals("Failure - 5 is a prime number.", true, numbers.isPrime(5) );
		assertEquals("Failure - 6 is not a prime number.", false, numbers.isPrime(6) );
		assertEquals("Failure - 7 is a prime number.", true, numbers.isPrime(7) );
		assertEquals("Failure - 8 is not a prime number.", false, numbers.isPrime(8) );
		assertEquals("Failure - 9 is not a prime number.", false, numbers.isPrime(9) );
		assertEquals("Failure - 10 is not a prime number.", false, numbers.isPrime(10) );
		assertEquals("Failure - 11 is a prime number.", true, numbers.isPrime(11) );
		// ...
	}

	@Test
	public void testFactorial() {
		assertEquals("Failure - Factorial wrong.", Integer.valueOf(6), numbers.factorial(3) );
		assertEquals("Failure - Factorial wrong.", Integer.valueOf(24), numbers.factorial(4) );
		// ...
	}

	@Test(expected = IllegalArgumentException.class)
	public void testFactorialException() {
		numbers.factorial(-1);
	}
	
	/*
	 * Deeper exception testing
	 */
	@Rule
	public ExpectedException thrown = ExpectedException.none();
	
	@Test
	public void testFactorialExceptionExt() throws IllegalArgumentException {
		thrown.expect(IllegalArgumentException.class);
	    thrown.expectMessage("Negative numbers are not allowed a argument.");
//	    thrown.expectMessage(startsWith("Negative numbers are not valid"));
		numbers.factorial(-1);
	}
	
	@Test
	public void testDoForever() {
		assertTrue("No Integer type has been returned", numbers.doForever() instanceof Integer );
	}

}
