#!/bin/bash set -euo pipefail if [[ $# -ne 1 ]]; then echo "$0 {kurumi}" 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 } # Encode a single message and verify output. function run_single_test { "$TOOL" "$2" > "$TEST_DIR/output.c" || die "$1 (encode)" echo -n -e "$2" > "$TEST_DIR/expected.txt" gcc -Wno-div-by-zero "$TEST_DIR/output.c" -o "$TEST_DIR/output.exe" \ || die "$1 (compile)" gcc -c "$TEST_DIR/output.c" -o /dev/null 2>&1 \ | "$TEST_DIR/output.exe" > "$TEST_DIR/actual.txt" \ || die "$1 (decode gcc)" diff -q "$TEST_DIR/expected.txt" "$TEST_DIR/actual.txt" \ || die "$1 (diff gcc)" clang -c "$TEST_DIR/output.c" -o /dev/null 2>&1 \ | "$TEST_DIR/output.exe" > "$TEST_DIR/actual.txt" \ || die "$1 (decode clang)" diff -q "$TEST_DIR/expected.txt" "$TEST_DIR/actual.txt" \ || die "$1 (diff clang)" ruby "$TEST_DIR/output.c" \ | "$TEST_DIR/output.exe" > "$TEST_DIR/actual.txt" \ || die "$1 (decode ruby)" diff -q "$TEST_DIR/expected.txt" "$TEST_DIR/actual.txt" \ || die "$1 (diff ruby)" perl "$TEST_DIR/output.c" \ | "$TEST_DIR/output.exe" > "$TEST_DIR/actual.txt" \ || die "$1 (decode perl)" diff -q "$TEST_DIR/expected.txt" "$TEST_DIR/actual.txt" \ || die "$1 (diff perl)" } # Encode two messages and verify output. function run_test { "$TOOL" "$2" "$3" > "$TEST_DIR/output.c" || die "$1 (encode)" echo -n -e "$2" > "$TEST_DIR/expected1.txt" echo -n -e "$3" > "$TEST_DIR/expected2.txt" gcc -Wno-div-by-zero "$TEST_DIR/output.c" -o "$TEST_DIR/output.exe" \ || die "$1 (compile)" gcc -c "$TEST_DIR/output.c" -o /dev/null 2>&1 \ | "$TEST_DIR/output.exe" > "$TEST_DIR/actual1.txt" \ || die "$1 (decode gcc)" diff -q "$TEST_DIR/expected1.txt" "$TEST_DIR/actual1.txt" \ || die "$1 (diff gcc)" clang -c "$TEST_DIR/output.c" -o /dev/null 2>&1 \ | "$TEST_DIR/output.exe" > "$TEST_DIR/actual2.txt" \ || die "$1 (decode clang)" diff -q "$TEST_DIR/expected2.txt" "$TEST_DIR/actual2.txt" \ || die "$1 (diff clang)" ruby "$TEST_DIR/output.c" \ | "$TEST_DIR/output.exe" > "$TEST_DIR/actual1.txt" \ || die "$1 (decode ruby)" diff -q "$TEST_DIR/expected1.txt" "$TEST_DIR/actual1.txt" \ || die "$1 (diff ruby)" perl "$TEST_DIR/output.c" \ | "$TEST_DIR/output.exe" > "$TEST_DIR/actual2.txt" \ || die "$1 (decode perl)" diff -q "$TEST_DIR/expected2.txt" "$TEST_DIR/actual2.txt" \ || die "$1 (diff perl)" } # Check for help message and nonzero exit code when ran without arguments. "$TOOL" > "$TEST_DIR/help.txt" && die "$LINENO: unexpected success" grep -qF "msg" "$TEST_DIR/help.txt" || die "$LINENO: missing help message" # Run encoder tests. run_single_test "$LINENO: empty" "" run_single_test "$LINENO: one byte" "A" run_single_test "$LINENO: escape (simple)" "\a\b\v\\\r\n\t" run_single_test "$LINENO: escape (hex mix)" "\x1\x011\x2g\x33G" hex255=$(perl -e "printf '\\x%x', \$_ foreach(1..255);") run_single_test "$LINENO: escape (hex exhaustive)" "$hex255" run_test "$LINENO: empty" "" "" run_test "$LINENO: one byte (same)" "a" "a" run_test "$LINENO: one byte (different)" "a" "b" run_test "$LINENO: multiple bytes (same)" "test" "test" run_test "$LINENO: multiple bytes (8 bit differences)" "hoge" "PIYO" run_test "$LINENO: multiple bytes (4 bit differences)" "AbCdEf" "aBStFg" run_test "$LINENO: different length (0 vs 1)" "" "1" run_test "$LINENO: different length (1 vs 0)" "1" "" run_test "$LINENO: different length (2 vs 6)" "uv" "uvwxyz" run_test "$LINENO: different length (6 vs 2)" "UVWXYZ" "UV" random1=$(perl -e "srand 1;foreach(1..192){printf '\\x%x', int(rand(254))+1;}") random2=$(perl -e "srand 2;foreach(1..256){printf '\\x%x', int(rand(254))+1;}") run_test "$LINENO: random (192)" "$random1" "$random1" run_test "$LINENO: random (256)" "$random2" "$random2" run_test "$LINENO: random (192 vs 256)" "$random1" "$random2" run_test "$LINENO: random (256 vs 192)" "$random2" "$random1" rm -rf "$TEST_DIR" exit 0