#!/bin/sh # SUSv3 compliant sort tests. # Public Domain, David Leonard 2022 . ./testing.sh # name cmd expected ./input stdin testing "" "tsort" "a\n" "" "a a\n" testing "" "tsort -" "a\n" "" "a a\n" testing "" "tsort input" "a\n" "a a\n" "" testing "tsort input (w/o eol)" "tsort input" "a\n" "a a" "" testing "" "tsort /dev/null" "" "" "" testing "tsort empty" tsort "" "" "" testing "tsort blank" tsort "" "" "\n" testing "tsort blanks" tsort "" "" "\n\n \t\n " # simple inputs having exactly one solution testing "tsort 1-edge" tsort "a\nb\n" "" "a b\n" testing "tsort 2-edge" tsort "a\nb\nc\n" "" "a b b c\n" # The following test helper accommodates future variable output because, as # tsort is allowed to emit any total ordering that satisfies its input, # should the implementation changes, these tests will remain valid. # # The idea is to verify that: # - each input word is present EXACTLY ONCE in tsort's output # - for each input pair 'a b', the occurrence of 'a' APPEARS BEFORE 'b' # - the exit code is 0 tsort_test () { fail= name="$1"; shift args="$*" if [ $VERBOSE ]; then echo "============" echo "echo \"$args\" | tsort >actual" fi echo "$args" | tsort >actual ec=$? if [ $ec -ne 0 ]; then fail "tsort exit $ec, expected 0" fi while [ $# -ne 0 ]; do a=$1; shift b=$1; shift aline=$(grep -nxF "$a" /dev/null 2>/dev/null ec=$? if [ $ec -eq 0 ]; then fail "$name: unexpected exit 0 ($*)" fi report "$name" } fail () { [ $VERBOSE ] && echo "ERROR: $*" fail=1 } report () { if [ $fail ]; then FAILCOUNT=$(($FAILCOUNT + 1)) echo "FAIL: $*" else echo "PASS: $*" fi } tsort_test "tsort empty2" tsort_test "tsort singleton" a a tsort_test "tsort simple" a b b c tsort_test "tsort 2singleton" a a b b tsort_test "tsort medium" a b a b b c tsort_test "tsort std.example" a b c c d e g g f g e f h h tsort_test "tsort prefixes" a aa aa aaa aaaa aaaaa a aaaaa tsort_test_err "tsort odd" a tsort_test_err "tsort odd2" a b c tsort_test_err "tsort cycle" a b b a exit $FAILCOUNT