import static org.junit.Assert.*;

import java.awt.Point;
import java.util.Arrays;
import java.util.List;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;

/**
 * Parametrisierter Test für die Klasse {@link MyMathImpl} unter Verwendung der 
 * {@link org.junit.runners.Parameterized.Parameter} Annotation.
 * 
 * Der Einfachtheit halber wird der parametrisierte Test hier lediglich für die Funktion 
 * {@link MyMathImpl#euclideanDistance(Point a, Point b)} demonstriert.
 */
@RunWith(Parameterized.class)
public class MyMathTestParametrized2 {

	MyMathImpl myMath = new MyMathImpl();

	@Parameter(0)
	public Point point1;

	@Parameter(1)
	public Point point2;
	
	@Parameter(2)
	public double expectedEuclideanDistance;	
	
	@Parameter(3)
	public double delta;	

	@Parameter(4)
	public Class<? extends Exception> expectedException;
	
	@Rule
	public ExpectedException thrown = ExpectedException.none();

	@Parameters
	public static List<Object[]> initTestCases() {
		return Arrays.asList(new Object[][] {
			
			// Testcase 1
			{ new Point(0, 0), new Point(3, 4), 5, 0, null },
			// Testcase 2
			{ new Point(2, 3), new Point(3, 4), 1.41, 0.01, null },
			// Testcase 3
			{ new Point(0, 0), null, 0, 0, IllegalArgumentException.class }			
			
		});
	
	}
	
	/*
	 * Each instance of initTestCases will be constructed with 
	 * the default constructor and fields annotated by @Parameter 
	 * will be initialized with the data values in the @Parameters method.
	 */
	@Test
	public void testEuclideanDistance() {
		if (expectedException != null) {
			thrown.expect(expectedException);
		}
		assertEquals("Failure - Euclidean Distance incorrect.", 
				expectedEuclideanDistance, 
				Math.round( myMath.euclideanDistance(point1, point2) * 100 ) / 100.0, 
				delta );
	}
	
}
