import junit.framework.TestCase;

/**
 * Test Program 3: Dynamic Programming
 * EID: js68634
 * Created by John Starich on 8/3/16.
 */
public class Program3Test extends TestCase {
	private int sum(int[] integers) {
		int total = 0;
		for(int i : integers) total += i;
		return total;
	}

	public void testInitialize() throws Exception {
		Program3 program = new Program3();
		int numClasses = 10, maxGrade = 3;
		GradeFunction gradeFunction = new SquareRootGradeFunction(numClasses, maxGrade);
		program.initialize(numClasses, maxGrade, gradeFunction);
		assertEquals(numClasses, program.getNumClasses());
		assertEquals(maxGrade, program.getMaxGrade());
		assertSame(gradeFunction, program.getGradeFunction());
	}

	public void testComputeHoursSquareRoot() throws Exception {
		Program3 program = new Program3();
		int n = 10;
		int H = 40;
		int maxGrade = 3;
		program.initialize(n, maxGrade, new SquareRootGradeFunction(n, maxGrade));

		assertEquals(H, sum(program.computeHours(H)));
	}

	public void testComputeGradesSquareRoot() throws Exception {
		Program3 program = new Program3();
		int n = 10;
		int H = 40;
		int maxGrade = 3;
		program.initialize(n, maxGrade, new SquareRootGradeFunction(n, maxGrade));
		assertEquals(22, sum(program.computeGrades(H)));
	}

	public void testComputeGradesCustom() throws Exception {
		Program3 program = new Program3();
		int n = 10;
		int H = 20;
		int maxGrade = 10;
		program.initialize(n, maxGrade, new CustomGradeFunction(n, maxGrade));

		assertEquals(35, sum(program.computeGrades(H)));
	}

	public void testMyGradeFunction() throws Exception {
		Program3 program = new Program3();
		int n = 10;
		int H = 40;
		int maxGrade = 10;
		program.initialize(n, maxGrade, new MyGradeFunction(n, maxGrade));
		assertEquals(H, sum(program.computeHours(H)));
		assertEquals(49, sum(program.computeGrades(H)));
	}

	/** Test successive calls to Program3 don't corrupt the state of the instance */
	public void testSuccessiveRunsOnProgram() throws Exception {
		Program3 program = new Program3();
		int n = 10;
		int H = 40;
		int maxGrade = 10;
		program.initialize(n, maxGrade, new SquareRootGradeFunction(n, maxGrade));
		assertEquals(H, sum(program.computeHours(H)));
		assertEquals(22, sum(program.computeGrades(H)));

		H = 20;
		assertEquals(15, sum(program.computeGrades(H)));

		H = 80;
		assertEquals(31, sum(program.computeGrades(H)));
	}

	/** Test case where no work can be done to improve the overall grade */
	public void testAllZeros() throws Exception {
		Program3 program = new Program3();
		int n = 10;
		int H = 40;
		int maxGrade = 10;
		program.initialize(n, maxGrade, new GradeFunction() {
			@Override
			public int grade(int classID, int hours) {
				return 0;
			}
		});
		assertEquals(0, sum(program.computeHours(H)));
		assertEquals(0, sum(program.computeGrades(H)));
	}

	/** Test another custom grade function for completeness sake. */
	public void testIncreaseOnClassId() throws Exception {
		Program3 program = new Program3();
		final int n = 10;
		int H = 40;
		final int maxGrade = 10;
		program.initialize(n, maxGrade, new GradeFunction() {
			@Override
			public int grade(int classID, int hours) {
				if(hours == n - classID) return Math.min(maxGrade, classID);
				return 0;
			}
		});
		assertEquals(40, sum(program.computeHours(H)));
		assertEquals(44, sum(program.computeGrades(H)));
	}

	/** Ensure that if every class is an easy-A then no work is done at all. */
	public void testAllMax() throws Exception {
		Program3 program = new Program3();
		int n = 10;
		int H = 40;
		final int maxGrade = 10;
		program.initialize(n, maxGrade, new GradeFunction() {
			@Override
			public int grade(int classID, int hours) {
				return maxGrade;
			}
		});
		assertEquals(0, sum(program.computeHours(H)));
		assertEquals(100, sum(program.computeGrades(H)));
	}
}
@@ -2373,32 +2373,371 @@
 puteGrades(H)));
+%0A%0A%09%09n = 20;%0A%09%09H = 40;%0A%09%09maxGrade = 10;%0A%09%09program.initialize(n, maxGrade, new SquareRootGradeFunction(n, maxGrade));%0A%09%09assertEquals(H, sum(program.computeHours(H)));%0A%09%09assertEquals(30, sum(program.computeGrades(H)));%0A%0A%09%09H = 20;%0A%09%09assertEquals(20, sum(program.computeGrades(H)));%0A%0A%09%09H = 80;%0A%09%09assertEquals(45, sum(program.computeGrades(H)));
 %0A%09%7D%0A%0A%09/** Test c

Add double initialize test