/**
 * CS-20  Asg4
 * ArrayUtilTest.java
 * Purpose: Unit test of the ArrayUtil class.
 *
 * @version 1.0 1/25/03
 * @author Ed Parrish
 */
public final class ArrayUtilTest {
    /**
     * Private constructor to prevent instantiating this utility class.
     */
    private ArrayUtilTest() { }

    /**
     * The main method begins execution of the tests.
     *
     * @param args not used
     */
    public static void main(final String[] args) {
        testMakeArray();
        testCopyArray();
        testBubbleSort();
        testBubbleSortPlus();
        testLinearSearch();
        testBinarySearch();
        testShowArray();
        testShowArray2();
        testRunTests();
        System.out.println("*** All tests passed ***");
    }

    /**
     * Convenience method to test for assertions.
     *
     * @param condition The test condition that must be true to pass.
     * @param message The reason for the failure.
     */
    public static void assertTrue(boolean condition, String message) {
        if (!condition) {
            throw new RuntimeException(message);
        }
    }

    /**
     * Test method: int[] makeArray(int)
     */
    public static void testMakeArray() {
        System.out.println("Testing makeArray");
        final int size = 10;
        int[] array = ArrayUtil.makeArray(size);
        assertTrue(array.length == size, "Wrong array length");
        for (int i = 0; i < array.length; i++) {
            assertTrue(array[i] >= ArrayUtil.LOW, "Array value too low");
            assertTrue(array[i] < ArrayUtil.HIGH, "Array value too high");
        }
    }

    /**
     * Test method: int[] copyArray(int[])
     */
    public static void testCopyArray() {
        System.out.println("Testing copyArray");
        int[] a = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        int[] a2 = ArrayUtil.copyArray(a);
        assertTrue(a.length == a2.length, "Wrong array length");
        for (int i = 0; i < a.length; i++) {
            assertTrue(a[i] == a2[i],
                "Wrong array value: s/b " + a[i] + " is " + a2[i]);
        }
        a[0] = 99;
        assertTrue(a[0] != a2[0], "Array not copied");
    }

    /**
     * Test method: void bubbleSort(int[])
     */
    public static void testBubbleSort() {
        System.out.println("Testing bubbleSort");
        int[] a = {22, 12, 17, 29, 5, 67, 99, 0, 87, 43};
        ArrayUtil.bubbleSort(a);
        assertTrue(a.length == 10, "Wrong array length");
        for (int i = 0; i < a.length - 1; i++) {
            assertTrue(a[i] < a[i + 1],
                "Array not sorted: " + a[i] + "," + a[i + 1]);
        }
        assertTrue(ArrayUtil.comparisons <= 90,
            "Too many comparisons: " + ArrayUtil.comparisons);
    }

    /**
     * Test method: void bubbleSortPlus(int[])
     */
    public static void testBubbleSortPlus() {
        System.out.println("Testing bubbleSortPlus");
        int[] a = {22, 12, 17, 29, 5, 67, 99, 0, 87, 43};
        ArrayUtil.bubbleSortPlus(a);
        assertTrue(a.length == 10, "Wrong array length");
        for (int i = 0; i < a.length - 1; i++) {
            assertTrue(a[i] < a[i + 1],
                "Array not sorted: " + a[i] + "," + a[i + 1]);
        }
        //needs access to number of comparisons -- s/b an accessor method
        assertTrue(ArrayUtil.comparisons <= 45,
            "Did not implement removal of unncecessary passes");
        int[] b = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        ArrayUtil.bubbleSortPlus(b);
        assertTrue(ArrayUtil.comparisons < 10,
            "Did not implement the no-swap test");
    }

    /**
     * Test method: int linearSearch(int[], int)
     */
    public static void testLinearSearch() {
        System.out.println("Testing linearSearch");
        int[] a = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        int index = ArrayUtil.linearSearch(a, 5);
        assertTrue(a.length == 10, "Wrong array length");
        assertTrue(index == 4, "Found wrong element index");
        index = ArrayUtil.linearSearch(a, 99);
        assertTrue(index == -1, "Found non-existant element");
    }

    /**
     * Test method: int binarySearch(int[], int)
     */
    public static void testBinarySearch() {
        System.out.println("Testing binarySearch");
        int[] a = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        int index = ArrayUtil.binarySearch(a, 5);
        assertTrue(a.length == 10, "Wrong array length");
        assertTrue(index == 4, "Found wrong element index");
        index = ArrayUtil.linearSearch(a, 99);
        assertTrue(index == -1, "Found non-existant element");
    }

    /**
     * Test method: void showArray(int[])
     */
    public static void testShowArray() {
        System.out.println("Testing showArray");
        int[] a = {1, 2, 3, 4, 5};
        System.out.print("- Should show numbers 1 to 5: ");
        ArrayUtil.showArray(a);
        assertTrue(a.length == 5, "Array length modified");
    }

    /**
     * Test method: void showArray(int[], int)
     */
    public static void testShowArray2() {
        System.out.println("Testing showArray");
        int[] a = {1, 2, 3, 4, 5};
        System.out.print("- Should show numbers 1 to 5: ");
        ArrayUtil.showArray(a, 0);
        assertTrue(a.length == 5, "Array length modified");
    }

    /**
     * Test method: void runTests(int[])
     */
    public static void testRunTests() {
        System.out.println("Testing runTests");
        int[] a = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        ArrayUtil.runTests(a);
        assertTrue(a.length == 10, "Array length modified");
    }
}

