t / t9902-completion.shon commit Merge branch 'wk/doc-in-linux-3.x-era' (0d07e98)
   1#!/bin/sh
   2#
   3# Copyright (c) 2012 Felipe Contreras
   4#
   5
   6test_description='test bash completion'
   7
   8. ./lib-bash.sh
   9
  10complete ()
  11{
  12        # do nothing
  13        return 0
  14}
  15
  16# Be careful when updating this list:
  17#
  18# (1) The build tree may have build artifact from different branch, or
  19#     the user's $PATH may have a random executable that may begin
  20#     with "git-check" that are not part of the subcommands this build
  21#     will ship, e.g.  "check-ignore".  The tests for completion for
  22#     subcommand names tests how "check" is expanded; we limit the
  23#     possible candidates to "checkout" and "check-attr" to make sure
  24#     "check-attr", which is known by the filter function as a
  25#     subcommand to be thrown out, while excluding other random files
  26#     that happen to begin with "check" to avoid letting them get in
  27#     the way.
  28#
  29# (2) A test makes sure that common subcommands are included in the
  30#     completion for "git <TAB>", and a plumbing is excluded.  "add",
  31#     "filter-branch" and "ls-files" are listed for this.
  32
  33GIT_TESTING_COMMAND_COMPLETION='add checkout check-attr filter-branch ls-files'
  34
  35. "$GIT_BUILD_DIR/contrib/completion/git-completion.bash"
  36
  37# We don't need this function to actually join words or do anything special.
  38# Also, it's cleaner to avoid touching bash's internal completion variables.
  39# So let's override it with a minimal version for testing purposes.
  40_get_comp_words_by_ref ()
  41{
  42        while [ $# -gt 0 ]; do
  43                case "$1" in
  44                cur)
  45                        cur=${_words[_cword]}
  46                        ;;
  47                prev)
  48                        prev=${_words[_cword-1]}
  49                        ;;
  50                words)
  51                        words=("${_words[@]}")
  52                        ;;
  53                cword)
  54                        cword=$_cword
  55                        ;;
  56                esac
  57                shift
  58        done
  59}
  60
  61print_comp ()
  62{
  63        local IFS=$'\n'
  64        echo "${COMPREPLY[*]}" > out
  65}
  66
  67run_completion ()
  68{
  69        local -a COMPREPLY _words
  70        local _cword
  71        _words=( $1 )
  72        test "${1: -1}" == ' ' && _words+=('')
  73        (( _cword = ${#_words[@]} - 1 ))
  74        __git_wrap__git_main && print_comp
  75}
  76
  77# Test high-level completion
  78# Arguments are:
  79# 1: typed text so far (cur)
  80# 2: expected completion
  81test_completion ()
  82{
  83        if test $# -gt 1
  84        then
  85                printf '%s\n' "$2" >expected
  86        else
  87                sed -e 's/Z$//' >expected
  88        fi &&
  89        run_completion "$1" &&
  90        test_cmp expected out
  91}
  92
  93# Test __gitcomp.
  94# The first argument is the typed text so far (cur); the rest are
  95# passed to __gitcomp.  Expected output comes is read from the
  96# standard input, like test_completion().
  97test_gitcomp ()
  98{
  99        local -a COMPREPLY &&
 100        sed -e 's/Z$//' >expected &&
 101        cur="$1" &&
 102        shift &&
 103        __gitcomp "$@" &&
 104        print_comp &&
 105        test_cmp expected out
 106}
 107
 108# Test __gitcomp_nl
 109# Arguments are:
 110# 1: current word (cur)
 111# -: the rest are passed to __gitcomp_nl
 112test_gitcomp_nl ()
 113{
 114        local -a COMPREPLY &&
 115        sed -e 's/Z$//' >expected &&
 116        cur="$1" &&
 117        shift &&
 118        __gitcomp_nl "$@" &&
 119        print_comp &&
 120        test_cmp expected out
 121}
 122
 123invalid_variable_name='${foo.bar}'
 124
 125test_expect_success '__gitcomp - trailing space - options' '
 126        test_gitcomp "--re" "--dry-run --reuse-message= --reedit-message=
 127                --reset-author" <<-EOF
 128        --reuse-message=Z
 129        --reedit-message=Z
 130        --reset-author Z
 131        EOF
 132'
 133
 134test_expect_success '__gitcomp - trailing space - config keys' '
 135        test_gitcomp "br" "branch. branch.autosetupmerge
 136                branch.autosetuprebase browser." <<-\EOF
 137        branch.Z
 138        branch.autosetupmerge Z
 139        branch.autosetuprebase Z
 140        browser.Z
 141        EOF
 142'
 143
 144test_expect_success '__gitcomp - option parameter' '
 145        test_gitcomp "--strategy=re" "octopus ours recursive resolve subtree" \
 146                "" "re" <<-\EOF
 147        recursive Z
 148        resolve Z
 149        EOF
 150'
 151
 152test_expect_success '__gitcomp - prefix' '
 153        test_gitcomp "branch.me" "remote merge mergeoptions rebase" \
 154                "branch.maint." "me" <<-\EOF
 155        branch.maint.merge Z
 156        branch.maint.mergeoptions Z
 157        EOF
 158'
 159
 160test_expect_success '__gitcomp - suffix' '
 161        test_gitcomp "branch.me" "master maint next pu" "branch." \
 162                "ma" "." <<-\EOF
 163        branch.master.Z
 164        branch.maint.Z
 165        EOF
 166'
 167
 168test_expect_success '__gitcomp - doesnt fail because of invalid variable name' '
 169        __gitcomp "$invalid_variable_name"
 170'
 171
 172read -r -d "" refs <<-\EOF
 173maint
 174master
 175next
 176pu
 177EOF
 178
 179test_expect_success '__gitcomp_nl - trailing space' '
 180        test_gitcomp_nl "m" "$refs" <<-EOF
 181        maint Z
 182        master Z
 183        EOF
 184'
 185
 186test_expect_success '__gitcomp_nl - prefix' '
 187        test_gitcomp_nl "--fixup=m" "$refs" "--fixup=" "m" <<-EOF
 188        --fixup=maint Z
 189        --fixup=master Z
 190        EOF
 191'
 192
 193test_expect_success '__gitcomp_nl - suffix' '
 194        test_gitcomp_nl "branch.ma" "$refs" "branch." "ma" "." <<-\EOF
 195        branch.maint.Z
 196        branch.master.Z
 197        EOF
 198'
 199
 200test_expect_success '__gitcomp_nl - no suffix' '
 201        test_gitcomp_nl "ma" "$refs" "" "ma" "" <<-\EOF
 202        maintZ
 203        masterZ
 204        EOF
 205'
 206
 207test_expect_success '__gitcomp_nl - doesnt fail because of invalid variable name' '
 208        __gitcomp_nl "$invalid_variable_name"
 209'
 210
 211test_expect_success 'basic' '
 212        run_completion "git " &&
 213        # built-in
 214        grep -q "^add \$" out &&
 215        # script
 216        grep -q "^filter-branch \$" out &&
 217        # plumbing
 218        ! grep -q "^ls-files \$" out &&
 219
 220        run_completion "git f" &&
 221        ! grep -q -v "^f" out
 222'
 223
 224test_expect_success 'double dash "git" itself' '
 225        test_completion "git --" <<-\EOF
 226        --paginate Z
 227        --no-pager Z
 228        --git-dir=
 229        --bare Z
 230        --version Z
 231        --exec-path Z
 232        --exec-path=
 233        --html-path Z
 234        --info-path Z
 235        --work-tree=
 236        --namespace=
 237        --no-replace-objects Z
 238        --help Z
 239        EOF
 240'
 241
 242test_expect_success 'double dash "git checkout"' '
 243        test_completion "git checkout --" <<-\EOF
 244        --quiet Z
 245        --ours Z
 246        --theirs Z
 247        --track Z
 248        --no-track Z
 249        --merge Z
 250        --conflict=
 251        --orphan Z
 252        --patch Z
 253        EOF
 254'
 255
 256test_expect_success 'general options' '
 257        test_completion "git --ver" "--version " &&
 258        test_completion "git --hel" "--help " &&
 259        test_completion "git --exe" <<-\EOF &&
 260        --exec-path Z
 261        --exec-path=
 262        EOF
 263        test_completion "git --htm" "--html-path " &&
 264        test_completion "git --pag" "--paginate " &&
 265        test_completion "git --no-p" "--no-pager " &&
 266        test_completion "git --git" "--git-dir=" &&
 267        test_completion "git --wor" "--work-tree=" &&
 268        test_completion "git --nam" "--namespace=" &&
 269        test_completion "git --bar" "--bare " &&
 270        test_completion "git --inf" "--info-path " &&
 271        test_completion "git --no-r" "--no-replace-objects "
 272'
 273
 274test_expect_success 'general options plus command' '
 275        test_completion "git --version check" "checkout " &&
 276        test_completion "git --paginate check" "checkout " &&
 277        test_completion "git --git-dir=foo check" "checkout " &&
 278        test_completion "git --bare check" "checkout " &&
 279        test_completion "git --exec-path=foo check" "checkout " &&
 280        test_completion "git --html-path check" "checkout " &&
 281        test_completion "git --no-pager check" "checkout " &&
 282        test_completion "git --work-tree=foo check" "checkout " &&
 283        test_completion "git --namespace=foo check" "checkout " &&
 284        test_completion "git --paginate check" "checkout " &&
 285        test_completion "git --info-path check" "checkout " &&
 286        test_completion "git --no-replace-objects check" "checkout "
 287'
 288
 289test_expect_success 'git --help completion' '
 290        test_completion "git --help ad" "add " &&
 291        test_completion "git --help core" "core-tutorial "
 292'
 293
 294test_expect_success 'setup for ref completion' '
 295        echo content >file1 &&
 296        echo more >file2 &&
 297        git add . &&
 298        git commit -m one &&
 299        git branch mybranch &&
 300        git tag mytag
 301'
 302
 303test_expect_success 'checkout completes ref names' '
 304        test_completion "git checkout m" <<-\EOF
 305        master Z
 306        mybranch Z
 307        mytag Z
 308        EOF
 309'
 310
 311test_expect_success 'show completes all refs' '
 312        test_completion "git show m" <<-\EOF
 313        master Z
 314        mybranch Z
 315        mytag Z
 316        EOF
 317'
 318
 319test_expect_success '<ref>: completes paths' '
 320        test_completion "git show mytag:f" <<-\EOF
 321        file1 Z
 322        file2 Z
 323        EOF
 324'
 325
 326test_expect_success 'complete tree filename with spaces' '
 327        echo content >"name with spaces" &&
 328        git add . &&
 329        git commit -m spaces &&
 330        test_completion "git show HEAD:nam" <<-\EOF
 331        name with spaces Z
 332        EOF
 333'
 334
 335test_expect_success 'complete tree filename with metacharacters' '
 336        echo content >"name with \${meta}" &&
 337        git add . &&
 338        git commit -m meta &&
 339        test_completion "git show HEAD:nam" <<-\EOF
 340        name with ${meta} Z
 341        name with spaces Z
 342        EOF
 343'
 344
 345test_expect_success 'send-email' '
 346        test_completion "git send-email --cov" "--cover-letter " &&
 347        test_completion "git send-email ma" "master "
 348'
 349
 350test_expect_success 'complete files' '
 351        git init tmp && cd tmp &&
 352        test_when_finished "cd .. && rm -rf tmp" &&
 353
 354        echo "expected" > .gitignore &&
 355        echo "out" >> .gitignore &&
 356
 357        git add .gitignore &&
 358        test_completion "git commit " ".gitignore" &&
 359
 360        git commit -m ignore &&
 361
 362        touch new &&
 363        test_completion "git add " "new" &&
 364
 365        git add new &&
 366        git commit -a -m new &&
 367        test_completion "git add " "" &&
 368
 369        git mv new modified &&
 370        echo modify > modified &&
 371        test_completion "git add " "modified" &&
 372
 373        touch untracked &&
 374
 375        : TODO .gitignore should not be here &&
 376        test_completion "git rm " <<-\EOF &&
 377        .gitignore
 378        modified
 379        EOF
 380
 381        test_completion "git clean " "untracked" &&
 382
 383        : TODO .gitignore should not be here &&
 384        test_completion "git mv " <<-\EOF &&
 385        .gitignore
 386        modified
 387        EOF
 388
 389        mkdir dir &&
 390        touch dir/file-in-dir &&
 391        git add dir/file-in-dir &&
 392        git commit -m dir &&
 393
 394        mkdir untracked-dir &&
 395
 396        : TODO .gitignore should not be here &&
 397        test_completion "git mv modified " <<-\EOF &&
 398        .gitignore
 399        dir
 400        modified
 401        untracked
 402        untracked-dir
 403        EOF
 404
 405        test_completion "git commit " "modified" &&
 406
 407        : TODO .gitignore should not be here &&
 408        test_completion "git ls-files " <<-\EOF
 409        .gitignore
 410        dir
 411        modified
 412        EOF
 413
 414        touch momified &&
 415        test_completion "git add mom" "momified"
 416'
 417
 418test_expect_failure 'complete with tilde expansion' '
 419        git init tmp && cd tmp &&
 420        test_when_finished "cd .. && rm -rf tmp" &&
 421
 422        touch ~/tmp/file &&
 423
 424        test_completion "git add ~/tmp/" "~/tmp/file"
 425'
 426
 427test_done