#!/bin/bash set -euo pipefail if [[ $# -ne 1 ]]; then echo "$0 {bf}" exit 1 fi TOOL=$1 TEST_DIR=$(mktemp -d) # Delete temporary directory and exit with nonzero status. function die { echo "$1" rm -rf "$TEST_DIR" exit 1 } # Run tool against input file and compare against expected output. function run_test { "$TOOL" "$TEST_DIR/code.txt" "$TEST_DIR/input.txt" > "$TEST_DIR/actual.txt" \ || die "$1 (file, run)" diff -q "$TEST_DIR/expected.txt" "$TEST_DIR/actual.txt" \ || die "$1 (file, diff)" "$TOOL" - "$TEST_DIR/input.txt" < "$TEST_DIR/code.txt" \ > "$TEST_DIR/actual.txt" \ || die "$1 (stdin, run)" diff -q "$TEST_DIR/expected.txt" "$TEST_DIR/actual.txt" \ || die "$1 (stdin, diff)" } # Check for error conditions. function run_error_test { "$TOOL" "$TEST_DIR/code.txt" > "$TEST_DIR/error.txt" 2>&1 \ && die "$1 (unexpected success)" grep -qF "$2" "$TEST_DIR/error.txt" || die "$1 (missing error message)" } # Try reading nonexistent files. run_error_test "$LINENO: nonexistent code" "Error loading program" touch "$TEST_DIR/code.txt" "$TOOL" "$TEST_DIR/code.txt" "$TEST_DIR/no_such_file.txt" \ > "$TEST_DIR/error.txt" 2>&1 \ && die "$LINENO: nonexistent data (unexpected success)" grep -qF "Error opening" "$TEST_DIR/error.txt" \ || die "$LINENO: nonexistent data (missing error message)" # Try empty input. touch "$TEST_DIR/input.txt" touch "$TEST_DIR/expected.txt" run_test "$LINENO: empty" # Try successful cases. echo "+++++ +++++ +++++ +++++ +++++ +++++ +++." > "$TEST_DIR/code.txt" echo -n "!" > "$TEST_DIR/expected.txt" run_test "$LINENO: output" echo "+++++ +++++ +++++ +++++ +++++ +++++ +++ >++[<.>-]" > "$TEST_DIR/code.txt" echo -n "!!" > "$TEST_DIR/expected.txt" run_test "$LINENO: loop" echo "++++[>++++[>++++<-]<-]>>+." > "$TEST_DIR/code.txt" echo -n "A" > "$TEST_DIR/expected.txt" run_test "$LINENO: nested loop" perl -e 'print ">" x 9999, "+" x 65, "."' > "$TEST_DIR/code.txt" run_test "$LINENO: large tape" echo "[+.]>[+[.]] >>++--[+.]--++[+.]" > "$TEST_DIR/code.txt" echo -n "" > "$TEST_DIR/expected.txt" run_test "$LINENO: skip block" echo "<<>> ++++ ++++[>++++<-] >+ >><< ." > "$TEST_DIR/code.txt" echo -n "!" > "$TEST_DIR/expected.txt" run_test "$LINENO: lazy bounds check" echo ",+[-.,+]" > "$TEST_DIR/code.txt" echo "copy" > "$TEST_DIR/input.txt" echo "copy" > "$TEST_DIR/expected.txt" run_test "$LINENO: read input" # Try failure cases. echo "[" > "$TEST_DIR/code.txt" run_error_test "$LINENO: unmatched ]" "Unmatched [" echo "]" > "$TEST_DIR/code.txt" run_error_test "$LINENO: unmatched ]" "Unmatched ]" echo "<+" > "$TEST_DIR/code.txt" run_error_test "$LINENO: operating on negative address" "negative address" echo "<." > "$TEST_DIR/code.txt" run_error_test "$LINENO: output from negative address" "negative address" echo "." > "$TEST_DIR/code.txt" run_error_test "$LINENO: uninitialized output (empty)" "uninitialized" echo "+>." > "$TEST_DIR/code.txt" run_error_test "$LINENO: uninitialized output (out of bounds)" "uninitialized" rm -rf "$TEST_DIR" exit 0