// BiggestTester.java
//
// ICS 22 / CSE 22 Fall 2010
// Code Example
//
// Below is an example of programmatic unit testing, where we write a
// program to test small parts (i.e., units) of a program.  The "small
// parts" can be classes, individual methods, individual behaviors (i.e.,
// interesting combinations of method calls), or even individual uses of
// a particular method.  Either way, our goal is the same: focus a
// microscope on some small part of our program, set up a situation whereby
// we can find out if there are problems and, if so, gain insight into what
// the problem is, using the following information:
//
//   * What input caused the problem
//   * What output was received
//   * What output was expected
//
// As we talked about in class, it's a good idea for a tester to print
// output only when there's a problem, as a way of helping you avoid
// the boring, repetitive work of reading and re-reading the tester's
// output to try to decide if there's a problem.  With this model, it's
// simple: if there's output, there's a problem; if there's no output,
// there's no problem.  In general, we want the tester to focus our
// attention on the things that still need work.
//
// Notice, too, the technique of using a method to implement a particular
// kind of test, using parameters to run that test more than once with
// different inputs and expected outputs.  This is a great way to cut down
// on the amount of duplicated code that you write in your tester.
// Duplicated code in a tester is just as bad as duplicated code anywhere
// else; even testers, in realistic contexts, need to be maintained over
// time, as requirements (and, therefore, the correct output in some cases)
// change over time.
//
// As you write testers that are longer, you won't be able to have just one
// test method that you can call repeatedly.  But if you want to run the
// same kind of test multiple times with different parameters and expected
// values, refactoring that code into a method is a big win.


public class BiggestTester
{
	public static void main(String[] args)
	{
		testBiggest(1, 0, 0, 0, 1);
		testBiggest(2, 2, 3, 3, 3);
		testBiggest(4, 4, 4, 4, 4);
		testBiggest(-1, 0, 2, 4, 4);
		testBiggest(-1, -3, -2, -4, -1);
		testBiggest(5, 2, 6, 4, 6);
		
		// Integer.MIN_VALUE is the minimum possible value that can be
		// stored in an int.
		testBiggest(Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE,
			Integer.MIN_VALUE, Integer.MIN_VALUE);
			
		// Integer.MAX_VALUE is the maximum possible value that can be
		// stored in an int.
		testBiggest(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE,
			Integer.MAX_VALUE, Integer.MAX_VALUE);
	}


	private static void testBiggest(int a, int b, int c, int d, int expected)
	{
		int result = Algorithms.biggest(a, b, c, d);
		
		if (result != expected)
		{
			System.out.println("Algorithms.biggest(" + a + ", " + b
				+ ", " + c + ", " + d + ") returned " + result
				+ ", expected " + expected);
		}
	}
}
