Merge branch 'jk/test'
[gitweb.git] / t / test-lib.sh
index 83889c4f4690d30fd2d5e969d5d445dfb47ad579..e331cadcff479a8d9de59590c44b0502653653f9 100644 (file)
@@ -3,12 +3,16 @@
 # Copyright (c) 2005 Junio C Hamano
 #
 
+# Keep the original TERM for say_color
+ORIGINAL_TERM=$TERM
+
 # For repeatability, reset the environment to known value.
 LANG=C
 LC_ALL=C
 PAGER=cat
 TZ=UTC
-export LANG LC_ALL PAGER TZ
+TERM=dumb
+export LANG LC_ALL PAGER TERM TZ
 EDITOR=:
 VISUAL=:
 unset GIT_EDITOR
@@ -38,6 +42,7 @@ export GIT_MERGE_VERBOSITY
 export GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME
 export GIT_COMMITTER_EMAIL GIT_COMMITTER_NAME
 export EDITOR VISUAL
+GIT_TEST_CMP=${GIT_TEST_CMP:-diff -u}
 
 # Protect ourselves from common misconfiguration to export
 # CDPATH into the environment
@@ -58,12 +63,14 @@ esac
 # This test checks if command xyzzy does the right thing...
 # '
 # . ./test-lib.sh
-
-[ "x$TERM" != "xdumb" ] &&
-       [ -t 1 ] &&
-       tput bold >/dev/null 2>&1 &&
-       tput setaf 1 >/dev/null 2>&1 &&
-       tput sgr0 >/dev/null 2>&1 &&
+[ "x$ORIGINAL_TERM" != "xdumb" ] && (
+               TERM=$ORIGINAL_TERM &&
+               export TERM &&
+               [ -t 1 ] &&
+               tput bold >/dev/null 2>&1 &&
+               tput setaf 1 >/dev/null 2>&1 &&
+               tput sgr0 >/dev/null 2>&1
+       ) &&
        color=t
 
 while test "$#" -ne 0
@@ -73,6 +80,8 @@ do
                debug=t; shift ;;
        -i|--i|--im|--imm|--imme|--immed|--immedi|--immedia|--immediat|--immediate)
                immediate=t; shift ;;
+       -l|--l|--lo|--lon|--long|--long-|--long-t|--long-te|--long-tes|--long-test|--long-tests)
+               export GIT_TEST_LONG=t; shift ;;
        -h|--h|--he|--hel|--help)
                help=t; shift ;;
        -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose)
@@ -80,7 +89,7 @@ do
        -q|--q|--qu|--qui|--quie|--quiet)
                quiet=t; shift ;;
        --no-color)
-           color=; shift ;;
+               color=; shift ;;
        --no-python)
                # noop now...
                shift ;;
@@ -91,6 +100,9 @@ done
 
 if test -n "$color"; then
        say_color () {
+               (
+               TERM=$ORIGINAL_TERM
+               export TERM
                case "$1" in
                        error) tput bold; tput setaf 1;; # bold red
                        skip)  tput bold; tput setaf 2;; # bold green
@@ -101,6 +113,7 @@ if test -n "$color"; then
                shift
                echo "* $*"
                tput sgr0
+               )
        }
 else
        say_color() {
@@ -142,7 +155,28 @@ test_count=0
 test_fixed=0
 test_broken=0
 
-trap 'echo >&5 "FATAL: Unexpected exit with code $?"; exit 1' exit
+die () {
+       echo >&5 "FATAL: Unexpected exit with code $?"
+       exit 1
+}
+
+trap 'die' exit
+
+# The semantics of the editor variables are that of invoking
+# sh -c "$EDITOR \"$@\"" files ...
+#
+# If our trash directory contains shell metacharacters, they will be
+# interpreted if we just set $EDITOR directly, so do a little dance with
+# environment variables to work around this.
+#
+# In particular, quoting isn't enough, as the path may contain the same quote
+# that we're using.
+test_set_editor () {
+       FAKE_EDITOR="$1"
+       export FAKE_EDITOR
+       VISUAL='"$FAKE_EDITOR"'
+       export VISUAL
+}
 
 test_tick () {
        if test -z "${test_tick+set}"
@@ -270,6 +304,40 @@ test_expect_code () {
        echo >&3 ""
 }
 
+# This is not among top-level (test_expect_success | test_expect_failure)
+# but is a prefix that can be used in the test script, like:
+#
+#      test_expect_success 'complain and die' '
+#           do something &&
+#           do something else &&
+#          test_must_fail git checkout ../outerspace
+#      '
+#
+# Writing this as "! git checkout ../outerspace" is wrong, because
+# the failure could be due to a segv.  We want a controlled failure.
+
+test_must_fail () {
+       "$@"
+       test $? -gt 0 -a $? -le 129
+}
+
+# test_cmp is a helper function to compare actual and expected output.
+# You can use it like:
+#
+#      test_expect_success 'foo works' '
+#              echo expected >expected &&
+#              foo >actual &&
+#              test_cmp expected actual
+#      '
+#
+# This could be written as either "cmp" or "diff -u", but:
+# - cmp's output is not nearly as easy to read as diff -u
+# - not all diff versions understand "-u"
+
+test_cmp() {
+       $GIT_TEST_CMP "$@"
+}
+
 # Most tests can use the created repository, but some may need to create more.
 # Usage: test_create_repo <directory>
 test_create_repo () {
@@ -279,7 +347,7 @@ test_create_repo () {
        repo="$1"
        mkdir "$repo"
        cd "$repo" || error "Cannot setup test environment"
-       "$GIT_EXEC_PATH/git" init --template=$GIT_EXEC_PATH/templates/blt/ >/dev/null 2>&1 ||
+       "$GIT_EXEC_PATH/git" init "--template=$GIT_EXEC_PATH/templates/blt/" >/dev/null 2>&1 ||
        error "cannot run git init -- have you built things yet?"
        mv .git/hooks .git/hooks-disabled
        cd "$owd"
@@ -302,7 +370,7 @@ test_done () {
        case "$test_failure" in
        0)
                # We could:
-               # cd .. && rm -fr trash
+               # cd .. && rm -fr 'trash directory'
                # but that means we forbid any tests that use their own
                # subdirectory from calling test_done without coming back
                # to where they started from.
@@ -320,7 +388,7 @@ test_done () {
 }
 
 # Test the binaries we have just built.  The tests are kept in
-# t/ subdirectory and are run in trash subdirectory.
+# t/ subdirectory and are run in 'trash directory' subdirectory.
 PATH=$(pwd)/..:$PATH
 GIT_EXEC_PATH=$(pwd)/..
 GIT_TEMPLATE_DIR=$(pwd)/../templates/blt
@@ -342,11 +410,20 @@ if ! test -x ../test-chmtime; then
        exit 1
 fi
 
+. ../GIT-BUILD-OPTIONS
+
 # Test repository
-test=trash
-rm -fr "$test"
-test_create_repo $test
-cd "$test"
+test="trash directory"
+rm -fr "$test" || {
+       trap - exit
+       echo >&5 "FATAL: Cannot prepare test area"
+       exit 1
+}
+
+test_create_repo "$test"
+# Use -P to resolve symlinks in our working directory so that the cwd
+# in subprocesses like git equals our $PWD (for pathname comparisons).
+cd -P "$test" || exit 1
 
 this_test=$(expr "./$0" : '.*/\(t[0-9]*\)-[^/]*$')
 for skp in $GIT_SKIP_TESTS