#!/bin/tcsh
#
# This is a testing script for CSC 101 Program 1.  If you're a 101 student,
# YOU ARE NOT EXPECTED TO UNDERSTAND WHAT'S IN THS SCRIPT.  All you need to do
# is use it by typing
#
#     ./run.csh
#
# in your copy of the program 1 testing directory, as described in
# http://users.csc.calpoly.edu/~gfisher/classes/101/programs/1/testing/plan.html
#
# While you're not expected to understand what's going on here, you are
# certainly welcome to read as much as you like.  The script is written in the
# "C Shell", which can be described as a "C-like shell scripting language".
#
# The first command line argument is the name of the program to be tested.  If
# $1 is not present, then the program tested is ../make_change, which is the
# required name for the program solution.  If $1 is present, it's assumed to be
# the name of a program in the parent directory of this testing script.  The
# point of having this first arg is to allow other programs than the correct
# solution to be tested, e.g., ../mc_bug.
#
# If $2 = "-q", for "quiet mode", then all messages about output differences
# are suppressed.  Quiet mode is used when this testing script is run from a
# full-class grading script, where being able to suppress individual student
# results is handy.
#
# If $2 = "-v", for "verbose mode", then additional output messages are
# printed.  Verbose mode can be used for debugging both the program, as well as
# the testing script itself.  And yes, the testing script can have bugs in it,
# just like the code can.  We'll discuss this idea in class.
#
# Enough with the commentary -- let's get to it.
#

#
# Count then test cases, for output in verbose mode.
#
set case = 1

#
# As a convenience, make the output and diffs dirs, if the don't already exist.
#
if (! -e diffs) mkdir diffs
if (! -e output) mkdir output

#
# Clear anything out of the output and diffs dirs.
#
rm -rf output/* diffs/* >& /dev/null

#
# If the first argument is empty, set the name of the program to be tested to
# ../make_change.
#
if ($1 == "") then
    set prog = ../make_change
else
    set prog = ../$1
endif

#
# Iterate through the files in the input subdir.  Note that the order of the
# files is not the order served up by a UNIX ls, but rather the order of the
# cases as listed in the test plan.  The file input/.cases has the input files
# listed in that planned order.
#
foreach f (`cat input/.cases`)

    #
    # Run the program on this input, putting the results in the output subdir
    #
    $prog < input/$f >& output/$f

    #
    # In verbose, print the test case number, the input, the expected output,
    # and the actual output.
    #
    if ($2 == "-v") then
	echo ""
	echo '**** TEST CASE' $case '****' 
	echo '***  INPUT' $f': ***' 
	cat input/$f
	echo '***  EXPECTED OUTPUT:  ***'
	cat expected-output/$f
	echo '***  ACTUAL OUTPUT:  ***'
	cat output/$f
    endif

    #
    # Difference actual and expected outputs.  If no diffs, say nothing.  If
    # diffs, output a reasonably understandable message.
    # 
    diff output/$f expected-output/$f >& diffs/$f
    if (-z diffs/$f) then
        rm diffs/$f
    else
	if ($2 != "-q") then
            echo ""
	    echo "For input/$f, your output differs from the expected output."
	    echo "    See the file diffs/$f for details."
        endif
	if ($2 == "-v") then
            echo '***  TEST CASE' $case 'FAILED'
            echo ""
        endif
    endif

    #
    # Increment the test case counter.
    #
    @ case = $case + 1

end

if ($2 == "-v") echo ""

#
# Computer the score.
#
./score.csh

# 
# LocalWords:  CSC arg mc diffs dirs mkdir prog endif subdir foreach subdirs
# LocalWords:  diff rm
#
