Example #1
0
void basicStructuralTests() {
    beginTest("Basic Structural Tests");

    /* This try ... catch system is designed to catch any errors that the
     * program explicitly generates.  It does not guard against runtime
     * crashes from errors like following a bad pointer, so if your
     * program crashes and pulls up the debugger, you should be looking
     * for memory errors.
     */
    try {

        /* The use of curly braces here introduces a new block scope.  We
         * use this so that we can construct multiple different priority
         * queues.
         */

        /* Basic test: Add 5 elements to the queue and ensure that
         * the size is correct at each step.
         */
        {
            logInfo("These tests will check size() isEmpty() without calling dequeueMin().");

            PQueue queue;
            checkCondition(queue.isEmpty(), "New priority queue should be empty.");
            checkCondition(queue.size() == 0, "New priority queue should have size 0.");

            for (int i = 0; i < 5; i++) {
                queue.enqueue("Test String");

                checkCondition(queue.size() == i + 1, "Queue should have proper size after inserting a value.");
                checkCondition(!queue.isEmpty(), "Queue containing elements should not be empty.");
                cout<<i<<endl;
            }
        }

        /* Slightly more complex test: Enqueue and dequeue elements, ensuring the
         * size matches at each step.
         */
        {
            logInfo("We're about to start calling dequeueMin().");
            PQueue queue;

            for (int i = 0; i < 5; i++) {
                queue.enqueue("Test String");
            }

            for (int i = 5; i > 0; i--) {
                checkCondition(queue.size() == i, "Queue should have proper size after dequeues.");
                checkCondition(!queue.isEmpty(), "Queue should not be empty before all elements are removed.");
                queue.dequeueMin();
            }

            checkCondition(queue.size() == 0, "After removing all elements, the queue should have size 0.");
            checkCondition(queue.isEmpty(), "After removing all elements, the queue should be empty.");
        }

        /* Getting harder: The value dequeued should always match the value of peek(). */
        {
            logInfo("This next test will check whether peek() matches dequeueMin().");
            PQueue queue;

            for (int i = 0; i < 5; i++) {
                queue.enqueue(randomString());
            }

            while (!queue.isEmpty()) {
                string expected = queue.peek();
                checkCondition(queue.dequeueMin() == expected, "Value returned by peek() matches value returned by dequeueMin()");
            }
        }

        /* A different one - let's make sure that peeking at an empty queue causes an
         * error.
         */
        {
            PQueue queue;
            bool didThrow = false;
            try {
                logInfo("About to peek into an empty queue.  This may cause a crash");
                logInfo("if your implementation is incorrect.");
                queue.peek();
            } catch (ErrorException&) {
                didThrow = true;
            }

            checkCondition(didThrow, "Priority queue uses 'error' when peek() called on empty queue.");
        }

        /* In the same vein - what happens if we dequeue from an empty queue? */
        {
            PQueue queue;
            bool didThrow = false;
            try {
                logInfo("About to dequeue from an empty queue.  This may cause a crash");
                logInfo("if your implementation is incorrect.");
                queue.dequeueMin();
            } catch (ErrorException&) {
                didThrow = true;
            }

            checkCondition(didThrow, "Priority queue uses 'error' when dequeueMin() called on empty queue.");
        }

    } catch (ErrorException& e) {
        cout << "TEST FAILURE: Unexpected exception: " << e.getMessage() << endl;
    } catch (exception& e) {
        cout << "TEST FAILURE: Unexpected exception: " << e.what() << endl;
    } catch (...) {
        cout << "TEST FAILURE: Unknown exception." << endl;
    }

    endTest("Basic Structural Tests");
}
Example #2
0
void sortRandomTests() {
    beginTest("Sort Random Tests");

    /* This try ... catch system is designed to catch any errors that the
     * program explicitly generates.  It does not guard against runtime
     * crashes from errors like following a bad pointer, so if your
     * program crashes and pulls up the debugger, you should be looking
     * for memory errors.
     */
    try {
        /* The use of curly braces here introduces a new block scope.  We
         * use this so that we can construct multiple different priority
         * queues.
         */

        /* Basic test: Feed the strings H through A into the priority queue in some order,
         * then confirm that they come back in sorted order
         */
        {
            logInfo("Enqueuing a random permutation of A - H and checking whether it leaves sorted.");
            Vector<string> letters;
            for (char ch = 'A'; ch <= 'H'; ch++) {
                /* The code
                 *
                 *    string(1, ch)
                 *
                 * converts the character ch into a one-character string.
                 */
                letters += string(1, ch);
            }

            /* Scramble the letters with the STL random_shuffle algorithm. */
            random_shuffle(letters.begin(), letters.end());

            /* Load the letters into the priority queue. */
            PQueue queue;
            foreach (string letter in letters)
                queue.enqueue(letter);

            /* Confirm they come back sorted. */
            for (char ch = 'A'; ch <= 'H'; ch++) {
                string expected(1, ch);
                checkCondition(queue.dequeueMin() == expected, "Queue should yield " + expected + ".");
            }
        }

        /* Harder test: Sort 10 random strings and confirm that the priority queue hands
         * them back in the same order.
         */
        {
            logInfo("Enqueuing 10 random strings and checking whether it leaves sorted.");
            /* Create 10 random strings. */
            Vector<string> randomValues;
            for (int i = 0; i < 10; i++) {
                randomValues += randomString();
            }

            /* Feed these values into the priority queue and pull them back out. */
            PQueue queue;
            foreach (string value in randomValues)
                queue.enqueue(value);

            /* Confirm each comes back correctly. */
            sort(randomValues.begin(), randomValues.end());
            for (int i = 0; i < randomValues.size(); i++) {
                checkCondition(queue.dequeueMin() == randomValues[i],
                               "Expecting to get value " + randomValues[i] + " from queue.");
            }
        }

        /* Much harder test: Sort 10000 random strings and confirm that the priority queue hands
         * them back in the same order.
         */
        {
            logInfo("Generating 10000 random strings.");
            Vector<string> randomValues;
            for (int i = 0; i < 10000; i++) {
                randomValues += randomString();
            }

            /* Feed these values into the priority queue and pull them back out. */
            logInfo("Enqueuing 10000 random strings.");
            PQueue queue;
            foreach (string value in randomValues)
                queue.enqueue(value);

            /* Use C++'s provided sorting routine to sort these values. */
            logInfo("Sorting 10000 random strings.");
            sort(randomValues.begin(), randomValues.end(), greater<string>());

            /* Confirm each comes back correctly. */
            logInfo("Dequeuing 10000 random strings.");
            bool isCorrect = true;
            reverse(randomValues.begin(), randomValues.end());
            for (int i = 0; i < randomValues.size(); i++) {
                if (queue.dequeueMin() != randomValues[i]) {
                    isCorrect = false;
                    break;
                }
            }

            checkCondition(isCorrect, "Queue correctly sorted 10000 random strings.");
        }

    } catch (ErrorException& e) {
        cout << "TEST FAILURE: Unexpected exception: " << e.getMessage() << endl;
    } catch (exception& e) {
        cout << "TEST FAILURE: Unexpected exception: " << e.what() << endl;
    } catch (...) {
        cout << "TEST FAILURE: Unknown exception." << endl;
    }

    endTest("Sort Random Tests");
}