t1300: demonstrate that --replace-all can "invent" newlines
[gitweb.git] / t / test-lib-functions.sh
index 4f7eadb5963e7d698f9ee6e265b1657e543cdb44..8a8a9329eeaa322121ecdbb3cd1f5fa6c9ecc94c 100644 (file)
@@ -42,6 +42,7 @@ test_decode_color () {
                function name(n) {
                        if (n == 0) return "RESET";
                        if (n == 1) return "BOLD";
+                       if (n == 7) return "REVERSE";
                        if (n == 30) return "BLACK";
                        if (n == 31) return "RED";
                        if (n == 32) return "GREEN";
@@ -81,6 +82,10 @@ test_decode_color () {
        '
 }
 
+lf_to_nul () {
+       perl -pe 'y/\012/\000/'
+}
+
 nul_to_q () {
        perl -pe 'y/\000/Q/'
 }
@@ -132,17 +137,12 @@ test_tick () {
        export GIT_COMMITTER_DATE GIT_AUTHOR_DATE
 }
 
-# Stop execution and start a shell. This is useful for debugging tests and
-# only makes sense together with "-v".
+# Stop execution and start a shell. This is useful for debugging tests.
 #
 # Be sure to remove all invocations of this command before submitting.
 
 test_pause () {
-       if test "$verbose" = t; then
-               "$SHELL_PATH" <&6 >&3 2>&4
-       else
-               error >&5 "test_pause requires --verbose"
-       fi
+       "$SHELL_PATH" <&6 >&5 2>&7
 }
 
 # Wrap git in gdb. Adding this to a command can make it easier to
@@ -150,19 +150,24 @@ test_pause () {
 #
 # Example: "debug git checkout master".
 debug () {
-        GIT_TEST_GDB=1 "$@"
+        GIT_TEST_GDB=1 "$@" <&6 >&5 2>&7
 }
 
-# Call test_commit with the arguments "<message> [<file> [<contents> [<tag>]]]"
+# Call test_commit with the arguments
+# [-C <directory>] <message> [<file> [<contents> [<tag>]]]"
 #
 # This will commit a file with the given contents and the given commit
 # message, and tag the resulting commit with the given tag name.
 #
 # <file>, <contents>, and <tag> all default to <message>.
+#
+# If the first argument is "-C", the second argument is used as a path for
+# the git invocations.
 
 test_commit () {
        notick= &&
        signoff= &&
+       indir= &&
        while test $# != 0
        do
                case "$1" in
@@ -172,21 +177,26 @@ test_commit () {
                --signoff)
                        signoff="$1"
                        ;;
+               -C)
+                       indir="$2"
+                       shift
+                       ;;
                *)
                        break
                        ;;
                esac
                shift
        done &&
+       indir=${indir:+"$indir"/} &&
        file=${2:-"$1.t"} &&
-       echo "${3-$1}" > "$file" &&
-       git add "$file" &&
+       echo "${3-$1}" > "$indir$file" &&
+       git ${indir:+ -C "$indir"} add "$file" &&
        if test -z "$notick"
        then
                test_tick
        fi &&
-       git commit $signoff -m "$1" &&
-       git tag "${4:-$1}"
+       git ${indir:+ -C "$indir"} commit $signoff -m "$1" &&
+       git ${indir:+ -C "$indir"} tag "${4:-$1}"
 }
 
 # Call test_merge with the arguments "<message> <commit>", where <commit>
@@ -207,6 +217,11 @@ test_chmod () {
        git update-index --add "--chmod=$@"
 }
 
+# Get the modebits from a file.
+test_modebits () {
+       ls -l "$1" | sed -e 's|^\(..........\).*|\1|'
+}
+
 # Unset a configuration variable, but don't fail if it doesn't exist.
 test_unconfig () {
        config_dir=
@@ -595,6 +610,14 @@ list_contains () {
 #
 # Writing this as "! git checkout ../outerspace" is wrong, because
 # the failure could be due to a segv.  We want a controlled failure.
+#
+# Accepts the following options:
+#
+#   ok=<signal-name>[,<...>]:
+#     Don't treat an exit caused by the given signal as error.
+#     Multiple signals can be specified as a comma separated list.
+#     Currently recognized signal names are: sigpipe, success.
+#     (Don't use 'success', use 'test_might_fail' instead.)
 
 test_must_fail () {
        case "$1" in
@@ -641,6 +664,8 @@ test_must_fail () {
 #
 # Writing "git config --unset all.configuration || :" would be wrong,
 # because we want to notice if it fails due to segv.
+#
+# Accepts the same options as test_must_fail.
 
 test_might_fail () {
        test_must_fail ok=success "$@"
@@ -690,6 +715,60 @@ test_cmp_bin() {
        cmp "$@"
 }
 
+# Use this instead of test_cmp to compare files that contain expected and
+# actual output from git commands that can be translated.  When running
+# under GETTEXT_POISON this pretends that the command produced expected
+# results.
+test_i18ncmp () {
+       test -n "$GETTEXT_POISON" || test_cmp "$@"
+}
+
+# Use this instead of "grep expected-string actual" to see if the
+# output from a git command that can be translated either contains an
+# expected string, or does not contain an unwanted one.  When running
+# under GETTEXT_POISON this pretends that the command produced expected
+# results.
+test_i18ngrep () {
+       eval "last_arg=\${$#}"
+
+       test -f "$last_arg" ||
+       error "bug in the test script: test_i18ngrep requires a file" \
+             "to read as the last parameter"
+
+       if test $# -lt 2 ||
+          { test "x!" = "x$1" && test $# -lt 3 ; }
+       then
+               error "bug in the test script: too few parameters to test_i18ngrep"
+       fi
+
+       if test -n "$GETTEXT_POISON"
+       then
+               # pretend success
+               return 0
+       fi
+
+       if test "x!" = "x$1"
+       then
+               shift
+               ! grep "$@" && return 0
+
+               echo >&2 "error: '! grep $@' did find a match in:"
+       else
+               grep "$@" && return 0
+
+               echo >&2 "error: 'grep $@' didn't find a match in:"
+       fi
+
+       if test -s "$last_arg"
+       then
+               cat >&2 "$last_arg"
+       else
+               echo >&2 "<File '$last_arg' is empty>"
+       fi
+
+       return 1
+}
+
 # Call any command "$@" but be more verbose about its
 # failure. This is handy for commands like "test" which do
 # not output anything when they fail.
@@ -985,8 +1064,57 @@ test_copy_bytes () {
                        my $s;
                        my $nread = sysread(STDIN, $s, $len);
                        die "cannot read: $!" unless defined($nread);
+                       last unless $nread;
                        print $s;
                        $len -= $nread;
                }
        ' - "$1"
 }
+
+# run "$@" inside a non-git directory
+nongit () {
+       test -d non-repo ||
+       mkdir non-repo ||
+       return 1
+
+       (
+               GIT_CEILING_DIRECTORIES=$(pwd) &&
+               export GIT_CEILING_DIRECTORIES &&
+               cd non-repo &&
+               "$@"
+       )
+}
+
+# convert stdin to pktline representation; note that empty input becomes an
+# empty packet, not a flush packet (for that you can just print 0000 yourself).
+packetize() {
+       cat >packetize.tmp &&
+       len=$(wc -c <packetize.tmp) &&
+       printf '%04x%s' "$(($len + 4))" &&
+       cat packetize.tmp &&
+       rm -f packetize.tmp
+}
+
+# Parse the input as a series of pktlines, writing the result to stdout.
+# Sideband markers are removed automatically, and the output is routed to
+# stderr if appropriate.
+#
+# NUL bytes are converted to "\\0" for ease of parsing with text tools.
+depacketize () {
+       perl -e '
+               while (read(STDIN, $len, 4) == 4) {
+                       if ($len eq "0000") {
+                               print "FLUSH\n";
+                       } else {
+                               read(STDIN, $buf, hex($len) - 4);
+                               $buf =~ s/\0/\\0/g;
+                               if ($buf =~ s/^[\x2\x3]//) {
+                                       print STDERR $buf;
+                               } else {
+                                       $buf =~ s/^\x1//;
+                                       print $buf;
+                               }
+                       }
+               }
+       '
+}