tsort.tests 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #!/bin/sh
  2. # SUSv3 compliant sort tests.
  3. # Public Domain, David Leonard 2022
  4. . ./testing.sh
  5. # name cmd expected ./input stdin
  6. testing "" "tsort" "a\n" "" "a a\n"
  7. testing "" "tsort -" "a\n" "" "a a\n"
  8. testing "" "tsort input" "a\n" "a a\n" ""
  9. testing "tsort input (w/o eol)" "tsort input" "a\n" "a a" ""
  10. testing "" "tsort /dev/null" "" "" ""
  11. testing "tsort empty" tsort "" "" ""
  12. testing "tsort blank" tsort "" "" "\n"
  13. testing "tsort blanks" tsort "" "" "\n\n \t\n "
  14. # simple inputs having exactly one solution
  15. testing "tsort 1-edge" tsort "a\nb\n" "" "a b\n"
  16. testing "tsort 2-edge" tsort "a\nb\nc\n" "" "a b b c\n"
  17. # The following test helper accommodates future variable output because, as
  18. # tsort is allowed to emit any total ordering that satisfies its input,
  19. # should the implementation changes, these tests will remain valid.
  20. #
  21. # The idea is to verify that:
  22. # - each input word is present EXACTLY ONCE in tsort's output
  23. # - for each input pair 'a b', the occurrence of 'a' APPEARS BEFORE 'b'
  24. # - the exit code is 0
  25. tsort_test () {
  26. fail=
  27. name="$1"; shift
  28. args="$*"
  29. if [ $VERBOSE ]; then
  30. echo "============"
  31. echo "echo \"$args\" | tsort >actual"
  32. fi
  33. echo "$args" | tsort >actual
  34. ec=$?
  35. if [ $ec -ne 0 ]; then
  36. fail "tsort exit $ec, expected 0"
  37. fi
  38. while [ $# -ne 0 ]; do
  39. a=$1; shift
  40. b=$1; shift
  41. aline=$(grep -nxF "$a" <actual | cut -d: -f1)
  42. bline=$(grep -nxF "$b" <actual | cut -d: -f1)
  43. case $aline in
  44. "") fail "word $a missing from output ($args)";;
  45. *" "*) fail "word $a duplicated ($args)";;
  46. esac
  47. case $bline in
  48. "") fail "word $b missing from output ($args)";;
  49. *" "*) fail "word $b duplicated ($args)";;
  50. esac
  51. if [ $aline -gt $bline ]; then
  52. fail "$a appears after $b ($args)"
  53. fi
  54. done
  55. if [ $fail ] && [ $VERBOSE ]; then
  56. echo "exit $ec, actual:"
  57. cat actual
  58. fi
  59. rm actual
  60. report "$name"
  61. }
  62. # Test that erroneous input causes an unsuccessful exit code
  63. # we don't test the output error message
  64. tsort_test_err () {
  65. fail=
  66. name="$1"; shift
  67. echo "$*" | tsort >/dev/null 2>/dev/null
  68. ec=$?
  69. if [ $ec -eq 0 ]; then
  70. fail "$name: unexpected exit 0 ($*)"
  71. fi
  72. report "$name"
  73. }
  74. fail () {
  75. [ $VERBOSE ] && echo "ERROR: $*"
  76. fail=1
  77. }
  78. report () {
  79. if [ $fail ]; then
  80. FAILCOUNT=$(($FAILCOUNT + 1))
  81. echo "FAIL: $*"
  82. else
  83. echo "PASS: $*"
  84. fi
  85. }
  86. tsort_test "tsort empty2"
  87. tsort_test "tsort singleton" a a
  88. tsort_test "tsort simple" a b b c
  89. tsort_test "tsort 2singleton" a a b b
  90. tsort_test "tsort medium" a b a b b c
  91. tsort_test "tsort std.example" a b c c d e g g f g e f h h
  92. tsort_test "tsort prefixes" a aa aa aaa aaaa aaaaa a aaaaa
  93. tsort_test_err "tsort odd" a
  94. tsort_test_err "tsort odd2" a b c
  95. tsort_test_err "tsort cycle" a b b a
  96. exit $FAILCOUNT