Merge branch 'jc/detached-head-doc'
[git] / t / t9902-completion.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2012 Felipe Contreras
4 #
5
6 test_description='test bash completion'
7
8 . ./lib-bash.sh
9
10 complete ()
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
33 GIT_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
61 print_comp ()
62 {
63         local IFS=$'\n'
64         echo "${COMPREPLY[*]}" > out
65 }
66
67 run_completion ()
68 {
69         local -a COMPREPLY _words
70         local _cword
71         _words=( $1 )
72         (( _cword = ${#_words[@]} - 1 ))
73         __git_wrap__git_main && print_comp
74 }
75
76 # Test high-level completion
77 # Arguments are:
78 # 1: typed text so far (cur)
79 # 2: expected completion
80 test_completion ()
81 {
82         if test $# -gt 1
83         then
84                 printf '%s\n' "$2" >expected
85         else
86                 sed -e 's/Z$//' >expected
87         fi &&
88         run_completion "$1" &&
89         test_cmp expected out
90 }
91
92 # Test __gitcomp.
93 # The first argument is the typed text so far (cur); the rest are
94 # passed to __gitcomp.  Expected output comes is read from the
95 # standard input, like test_completion().
96 test_gitcomp ()
97 {
98         local -a COMPREPLY &&
99         sed -e 's/Z$//' >expected &&
100         cur="$1" &&
101         shift &&
102         __gitcomp "$@" &&
103         print_comp &&
104         test_cmp expected out
105 }
106
107 test_expect_success '__gitcomp - trailing space - options' '
108         test_gitcomp "--re" "--dry-run --reuse-message= --reedit-message=
109                 --reset-author" <<-EOF
110         --reuse-message=Z
111         --reedit-message=Z
112         --reset-author Z
113         EOF
114 '
115
116 test_expect_success '__gitcomp - trailing space - config keys' '
117         test_gitcomp "br" "branch. branch.autosetupmerge
118                 branch.autosetuprebase browser." <<-\EOF
119         branch.Z
120         branch.autosetupmerge Z
121         branch.autosetuprebase Z
122         browser.Z
123         EOF
124 '
125
126 test_expect_success '__gitcomp - option parameter' '
127         test_gitcomp "--strategy=re" "octopus ours recursive resolve subtree" \
128                 "" "re" <<-\EOF
129         recursive Z
130         resolve Z
131         EOF
132 '
133
134 test_expect_success '__gitcomp - prefix' '
135         test_gitcomp "branch.me" "remote merge mergeoptions rebase" \
136                 "branch.maint." "me" <<-\EOF
137         branch.maint.merge Z
138         branch.maint.mergeoptions Z
139         EOF
140 '
141
142 test_expect_success '__gitcomp - suffix' '
143         test_gitcomp "branch.me" "master maint next pu" "branch." \
144                 "ma" "." <<-\EOF
145         branch.master.Z
146         branch.maint.Z
147         EOF
148 '
149
150 test_expect_success 'basic' '
151         run_completion "git \"\"" &&
152         # built-in
153         grep -q "^add \$" out &&
154         # script
155         grep -q "^filter-branch \$" out &&
156         # plumbing
157         ! grep -q "^ls-files \$" out &&
158
159         run_completion "git f" &&
160         ! grep -q -v "^f" out
161 '
162
163 test_expect_success 'double dash "git" itself' '
164         test_completion "git --" <<-\EOF
165         --paginate Z
166         --no-pager Z
167         --git-dir=
168         --bare Z
169         --version Z
170         --exec-path Z
171         --exec-path=
172         --html-path Z
173         --info-path Z
174         --work-tree=
175         --namespace=
176         --no-replace-objects Z
177         --help Z
178         EOF
179 '
180
181 test_expect_success 'double dash "git checkout"' '
182         test_completion "git checkout --" <<-\EOF
183         --quiet Z
184         --ours Z
185         --theirs Z
186         --track Z
187         --no-track Z
188         --merge Z
189         --conflict=
190         --orphan Z
191         --patch Z
192         EOF
193 '
194
195 test_expect_success 'general options' '
196         test_completion "git --ver" "--version " &&
197         test_completion "git --hel" "--help " &&
198         test_completion "git --exe" <<-\EOF &&
199         --exec-path Z
200         --exec-path=
201         EOF
202         test_completion "git --htm" "--html-path " &&
203         test_completion "git --pag" "--paginate " &&
204         test_completion "git --no-p" "--no-pager " &&
205         test_completion "git --git" "--git-dir=" &&
206         test_completion "git --wor" "--work-tree=" &&
207         test_completion "git --nam" "--namespace=" &&
208         test_completion "git --bar" "--bare " &&
209         test_completion "git --inf" "--info-path " &&
210         test_completion "git --no-r" "--no-replace-objects "
211 '
212
213 test_expect_success 'general options plus command' '
214         test_completion "git --version check" "checkout " &&
215         test_completion "git --paginate check" "checkout " &&
216         test_completion "git --git-dir=foo check" "checkout " &&
217         test_completion "git --bare check" "checkout " &&
218         test_completion "git --exec-path=foo check" "checkout " &&
219         test_completion "git --html-path check" "checkout " &&
220         test_completion "git --no-pager check" "checkout " &&
221         test_completion "git --work-tree=foo check" "checkout " &&
222         test_completion "git --namespace=foo check" "checkout " &&
223         test_completion "git --paginate check" "checkout " &&
224         test_completion "git --info-path check" "checkout " &&
225         test_completion "git --no-replace-objects check" "checkout "
226 '
227
228 test_expect_success 'git --help completion' '
229         test_completion "git --help ad" "add " &&
230         test_completion "git --help core" "core-tutorial "
231 '
232
233 test_expect_success 'setup for ref completion' '
234         echo content >file1 &&
235         echo more >file2 &&
236         git add . &&
237         git commit -m one &&
238         git branch mybranch &&
239         git tag mytag
240 '
241
242 test_expect_success 'checkout completes ref names' '
243         test_completion "git checkout m" <<-\EOF
244         master Z
245         mybranch Z
246         mytag Z
247         EOF
248 '
249
250 test_expect_success 'show completes all refs' '
251         test_completion "git show m" <<-\EOF
252         master Z
253         mybranch Z
254         mytag Z
255         EOF
256 '
257
258 test_expect_success '<ref>: completes paths' '
259         test_completion "git show mytag:f" <<-\EOF
260         file1 Z
261         file2 Z
262         EOF
263 '
264
265 test_expect_success 'complete tree filename with spaces' '
266         echo content >"name with spaces" &&
267         git add . &&
268         git commit -m spaces &&
269         test_completion "git show HEAD:nam" <<-\EOF
270         name with spaces Z
271         EOF
272 '
273
274 test_expect_failure 'complete tree filename with metacharacters' '
275         echo content >"name with \${meta}" &&
276         git add . &&
277         git commit -m meta &&
278         test_completion "git show HEAD:nam" <<-\EOF
279         name with ${meta} Z
280         name with spaces Z
281         EOF
282 '
283
284 test_expect_success 'send-email' '
285         test_completion "git send-email --cov" "--cover-letter " &&
286         test_completion "git send-email ma" "master "
287 '
288
289 test_done