ref-filter: factor ref_array pushing into its own function
[gitweb.git] / t / t3070-wildmatch.sh
index 3e75cb0cbed87ced2611cbc2dd1d1adf9e4e7c71..c1fc6ca7301eaa9b15ef091ce592989956efc156 100755 (executable)
@@ -4,6 +4,72 @@ test_description='wildmatch tests'
 
 . ./test-lib.sh
 
+should_create_test_file() {
+       file=$1
+
+       case $file in
+       # `touch .` will succeed but obviously not do what we intend
+       # here.
+       ".")
+               return 1
+               ;;
+       # We cannot create a file with an empty filename.
+       "")
+               return 1
+               ;;
+       # The tests that are testing that e.g. foo//bar is matched by
+       # foo/*/bar can't be tested on filesystems since there's no
+       # way we're getting a double slash.
+       *//*)
+               return 1
+               ;;
+       # When testing the difference between foo/bar and foo/bar/ we
+       # can't test the latter.
+       */)
+               return 1
+               ;;
+       # On Windows, \ in paths is silently converted to /, which
+       # would result in the "touch" below working, but the test
+       # itself failing. See 6fd1106aa4 ("t3700: Skip a test with
+       # backslashes in pathspec", 2009-03-13) for prior art and
+       # details.
+       *\\*)
+               if ! test_have_prereq BSLASHPSPEC
+               then
+                       return 1
+               fi
+               # NOTE: The ;;& bash extension is not portable, so
+               # this test needs to be at the end of the pattern
+               # list.
+               #
+               # If we want to add more conditional returns we either
+               # need a new case statement, or turn this whole thing
+               # into a series of "if" tests.
+               ;;
+       esac
+
+
+       # On Windows proper (i.e. not Cygwin) many file names which
+       # under Cygwin would be emulated don't work.
+       if test_have_prereq MINGW
+       then
+               case $file in
+               " ")
+                       # Files called " " are forbidden on Windows
+                       return 1
+                       ;;
+               *\<*|*\>*|*:*|*\"*|*\|*|*\?*|*\**)
+                       # Files with various special characters aren't
+                       # allowed on Windows. Sourced from
+                       # https://stackoverflow.com/a/31976060
+                       return 1
+                       ;;
+               esac
+       fi
+
+       return 0
+}
+
 match_with_function() {
        text=$1
        pattern=$2
@@ -26,25 +92,133 @@ match_with_function() {
 
 }
 
+match_with_ls_files() {
+       text=$1
+       pattern=$2
+       match_expect=$3
+       match_function=$4
+       ls_files_args=$5
+
+       match_stdout_stderr_cmp="
+               tr -d '\0' <actual.raw >actual &&
+               >expect.err &&
+               test_cmp expect.err actual.err &&
+               test_cmp expect actual"
+
+       if test "$match_expect" = 'E'
+       then
+               if test -e .git/created_test_file
+               then
+                       test_expect_success EXPENSIVE_ON_WINDOWS "$match_function (via ls-files): match dies on '$pattern' '$text'" "
+                               printf '%s' '$text' >expect &&
+                               test_must_fail git$ls_files_args ls-files -z -- '$pattern'
+                       "
+               else
+                       test_expect_failure EXPENSIVE_ON_WINDOWS "$match_function (via ls-files): match skip '$pattern' '$text'" 'false'
+               fi
+       elif test "$match_expect" = 1
+       then
+               if test -e .git/created_test_file
+               then
+                       test_expect_success EXPENSIVE_ON_WINDOWS "$match_function (via ls-files): match '$pattern' '$text'" "
+                               printf '%s' '$text' >expect &&
+                               git$ls_files_args ls-files -z -- '$pattern' >actual.raw 2>actual.err &&
+                               $match_stdout_stderr_cmp
+                       "
+               else
+                       test_expect_failure EXPENSIVE_ON_WINDOWS "$match_function (via ls-files): match skip '$pattern' '$text'" 'false'
+               fi
+       elif test "$match_expect" = 0
+       then
+               if test -e .git/created_test_file
+               then
+                       test_expect_success EXPENSIVE_ON_WINDOWS "$match_function (via ls-files): no match '$pattern' '$text'" "
+                               >expect &&
+                               git$ls_files_args ls-files -z -- '$pattern' >actual.raw 2>actual.err &&
+                               $match_stdout_stderr_cmp
+                       "
+               else
+                       test_expect_failure EXPENSIVE_ON_WINDOWS "$match_function (via ls-files): no match skip '$pattern' '$text'" 'false'
+               fi
+       else
+               test_expect_success "PANIC: Test framework error. Unknown matches value $match_expect" 'false'
+       fi
+}
+
 match() {
-       match_glob=$1
-       match_iglob=$2
-       match_pathmatch=$3
-       match_pathmatchi=$4
-       text=$5
-       pattern=$6
+       if test "$#" = 6
+       then
+               # When test-wildmatch and git ls-files produce the same
+               # result.
+               match_glob=$1
+               match_file_glob=$match_glob
+               match_iglob=$2
+               match_file_iglob=$match_iglob
+               match_pathmatch=$3
+               match_file_pathmatch=$match_pathmatch
+               match_pathmatchi=$4
+               match_file_pathmatchi=$match_pathmatchi
+               text=$5
+               pattern=$6
+       elif test "$#" = 10
+       then
+               match_glob=$1
+               match_iglob=$2
+               match_pathmatch=$3
+               match_pathmatchi=$4
+               match_file_glob=$5
+               match_file_iglob=$6
+               match_file_pathmatch=$7
+               match_file_pathmatchi=$8
+               text=$9
+               pattern=${10}
+       fi
+
+       test_expect_success EXPENSIVE_ON_WINDOWS 'cleanup after previous file test' '
+               if test -e .git/created_test_file
+               then
+                       git reset &&
+                       git clean -df
+               fi
+       '
+
+       printf '%s' "$text" >.git/expected_test_file
+
+       test_expect_success EXPENSIVE_ON_WINDOWS "setup match file test for $text" '
+               file=$(cat .git/expected_test_file) &&
+               if should_create_test_file "$file"
+               then
+                       dirs=${file%/*}
+                       if test "$file" != "$dirs"
+                       then
+                               mkdir -p -- "$dirs" &&
+                               touch -- "./$text"
+                       else
+                               touch -- "./$file"
+                       fi &&
+                       git add -A &&
+                       printf "%s" "$file" >.git/created_test_file
+               elif test -e .git/created_test_file
+               then
+                       rm .git/created_test_file
+               fi
+       '
 
        # $1: Case sensitive glob match: test-wildmatch & ls-files
        match_with_function "$text" "$pattern" $match_glob "wildmatch"
+       match_with_ls_files "$text" "$pattern" $match_file_glob "wildmatch" " --glob-pathspecs"
 
        # $2: Case insensitive glob match: test-wildmatch & ls-files
        match_with_function "$text" "$pattern" $match_iglob "iwildmatch"
+       match_with_ls_files "$text" "$pattern" $match_file_iglob "iwildmatch" " --glob-pathspecs --icase-pathspecs"
 
        # $3: Case sensitive path match: test-wildmatch & ls-files
        match_with_function "$text" "$pattern" $match_pathmatch "pathmatch"
+       match_with_ls_files "$text" "$pattern" $match_file_pathmatch "pathmatch" ""
 
        # $4: Case insensitive path match: test-wildmatch & ls-files
        match_with_function "$text" "$pattern" $match_pathmatchi "ipathmatch"
+       match_with_ls_files "$text" "$pattern" $match_file_pathmatchi "ipathmatch" " --icase-pathspecs"
 }
 
 # Basic wildmatch features
@@ -113,7 +287,8 @@ match 1 1 1 1 'acrt' 'a[c-c]rt'
 match 0 0 0 0 ']' '[!]-]'
 match 1 1 1 1 'a' '[!]-]'
 match 0 0 0 0 '' '\'
-match 0 0 0 0 '\' '\'
+match 0 0 0 0 \
+      1 1 1 1 '\' '\'
 match 0 0 0 0 'XXX/\' '*/\'
 match 1 1 1 1 'XXX/\' '*/\\'
 match 1 1 1 1 'foo' 'foo'
@@ -127,7 +302,8 @@ match 1 1 1 1 '[ab]' '[[:digit]ab]'
 match 1 1 1 1 '[ab]' '[\[:]ab]'
 match 1 1 1 1 '?a?b' '\??\?b'
 match 1 1 1 1 'abc' '\a\b\c'
-match 0 0 0 0 'foo' ''
+match 0 0 0 0 \
+      E E E E 'foo' ''
 match 1 1 1 1 'foo/bar/baz/to' '**/t[o]'
 
 # Character class tests
@@ -157,8 +333,10 @@ match 1 1 1 1 ']' '[\]]'
 match 0 0 0 0 '\]' '[\]]'
 match 0 0 0 0 '\' '[\]]'
 match 0 0 0 0 'ab' 'a[]b'
-match 0 0 0 0 'a[]b' 'a[]b'
-match 0 0 0 0 'ab[' 'ab['
+match 0 0 0 0 \
+      1 1 1 1 'a[]b' 'a[]b'
+match 0 0 0 0 \
+      1 1 1 1 'ab[' 'ab['
 match 0 0 0 0 'ab' '[!'
 match 0 0 0 0 'ab' '[-'
 match 1 1 1 1 '-' '[-]'
@@ -226,7 +404,8 @@ match 1 1 1 1 foo/bar 'foo/*'
 match 0 0 1 1 foo/bba/arr 'foo/*'
 match 1 1 1 1 foo/bba/arr 'foo/**'
 match 0 0 1 1 foo/bba/arr 'foo*'
-match 0 0 1 1 foo/bba/arr 'foo**'
+match 0 0 1 1 \
+      1 1 1 1 foo/bba/arr 'foo**'
 match 0 0 1 1 foo/bba/arr 'foo/*arr'
 match 0 0 1 1 foo/bba/arr 'foo/**arr'
 match 0 0 0 0 foo/bba/arr 'foo/*z'