Merge branch 'jc/no-need-for-env-in-sh-scripts'
[git] / t / t7006-pager.sh
1 #!/bin/sh
2
3 test_description='Test automatic use of a pager.'
4
5 . ./test-lib.sh
6 . "$TEST_DIRECTORY"/lib-pager.sh
7 . "$TEST_DIRECTORY"/lib-terminal.sh
8
9 test_expect_success 'setup' '
10         sane_unset GIT_PAGER GIT_PAGER_IN_USE &&
11         test_unconfig core.pager &&
12
13         PAGER="cat >paginated.out" &&
14         export PAGER &&
15
16         test_commit initial
17 '
18
19 test_expect_success TTY 'some commands use a pager' '
20         rm -f paginated.out &&
21         test_terminal git log &&
22         test -e paginated.out
23 '
24
25 test_expect_failure TTY 'pager runs from subdir' '
26         echo subdir/paginated.out >expected &&
27         mkdir -p subdir &&
28         rm -f paginated.out subdir/paginated.out &&
29         (
30                 cd subdir &&
31                 test_terminal git log
32         ) &&
33         {
34                 ls paginated.out subdir/paginated.out ||
35                 :
36         } >actual &&
37         test_cmp expected actual
38 '
39
40 test_expect_success TTY 'LESS and LV envvars are set for pagination' '
41         (
42                 sane_unset LESS LV &&
43                 PAGER="env >pager-env.out; wc" &&
44                 export PAGER &&
45
46                 test_terminal git log
47         ) &&
48         grep ^LESS= pager-env.out &&
49         grep ^LV= pager-env.out
50 '
51
52 test_expect_success TTY 'some commands do not use a pager' '
53         rm -f paginated.out &&
54         test_terminal git rev-list HEAD &&
55         ! test -e paginated.out
56 '
57
58 test_expect_success 'no pager when stdout is a pipe' '
59         rm -f paginated.out &&
60         git log | cat &&
61         ! test -e paginated.out
62 '
63
64 test_expect_success 'no pager when stdout is a regular file' '
65         rm -f paginated.out &&
66         git log >file &&
67         ! test -e paginated.out
68 '
69
70 test_expect_success TTY 'git --paginate rev-list uses a pager' '
71         rm -f paginated.out &&
72         test_terminal git --paginate rev-list HEAD &&
73         test -e paginated.out
74 '
75
76 test_expect_success 'no pager even with --paginate when stdout is a pipe' '
77         rm -f file paginated.out &&
78         git --paginate log | cat &&
79         ! test -e paginated.out
80 '
81
82 test_expect_success TTY 'no pager with --no-pager' '
83         rm -f paginated.out &&
84         test_terminal git --no-pager log &&
85         ! test -e paginated.out
86 '
87
88 test_expect_success TTY 'configuration can disable pager' '
89         rm -f paginated.out &&
90         test_unconfig pager.grep &&
91         test_terminal git grep initial &&
92         test -e paginated.out &&
93
94         rm -f paginated.out &&
95         test_config pager.grep false &&
96         test_terminal git grep initial &&
97         ! test -e paginated.out
98 '
99
100 test_expect_success TTY 'git config uses a pager if configured to' '
101         rm -f paginated.out &&
102         test_config pager.config true &&
103         test_terminal git config --list &&
104         test -e paginated.out
105 '
106
107 test_expect_success TTY 'configuration can enable pager (from subdir)' '
108         rm -f paginated.out &&
109         mkdir -p subdir &&
110         test_config pager.bundle true &&
111
112         git bundle create test.bundle --all &&
113         rm -f paginated.out subdir/paginated.out &&
114         (
115                 cd subdir &&
116                 test_terminal git bundle unbundle ../test.bundle
117         ) &&
118         {
119                 test -e paginated.out ||
120                 test -e subdir/paginated.out
121         }
122 '
123
124 # A colored commit log will begin with an appropriate ANSI escape
125 # for the first color; the text "commit" comes later.
126 colorful() {
127         read firstline <$1
128         ! expr "$firstline" : "[a-zA-Z]" >/dev/null
129 }
130
131 test_expect_success 'tests can detect color' '
132         rm -f colorful.log colorless.log &&
133         git log --no-color >colorless.log &&
134         git log --color >colorful.log &&
135         ! colorful colorless.log &&
136         colorful colorful.log
137 '
138
139 test_expect_success 'no color when stdout is a regular file' '
140         rm -f colorless.log &&
141         test_config color.ui auto &&
142         git log >colorless.log &&
143         ! colorful colorless.log
144 '
145
146 test_expect_success TTY 'color when writing to a pager' '
147         rm -f paginated.out &&
148         test_config color.ui auto &&
149         (
150                 TERM=vt100 &&
151                 export TERM &&
152                 test_terminal git log
153         ) &&
154         colorful paginated.out
155 '
156
157 test_expect_success TTY 'colors are suppressed by color.pager' '
158         rm -f paginated.out &&
159         test_config color.ui auto &&
160         test_config color.pager false &&
161         (
162                 TERM=vt100 &&
163                 export TERM &&
164                 test_terminal git log
165         ) &&
166         ! colorful paginated.out
167 '
168
169 test_expect_success 'color when writing to a file intended for a pager' '
170         rm -f colorful.log &&
171         test_config color.ui auto &&
172         (
173                 TERM=vt100 &&
174                 GIT_PAGER_IN_USE=true &&
175                 export TERM GIT_PAGER_IN_USE &&
176                 git log >colorful.log
177         ) &&
178         colorful colorful.log
179 '
180
181 test_expect_success TTY 'colors are sent to pager for external commands' '
182         test_config alias.externallog "!git log" &&
183         test_config color.ui auto &&
184         (
185                 TERM=vt100 &&
186                 export TERM &&
187                 test_terminal git -p externallog
188         ) &&
189         colorful paginated.out
190 '
191
192 # Use this helper to make it easy for the caller of your
193 # terminal-using function to specify whether it should fail.
194 # If you write
195 #
196 #       your_test() {
197 #               parse_args "$@"
198 #
199 #               $test_expectation "$cmd - behaves well" "
200 #                       ...
201 #                       $full_command &&
202 #                       ...
203 #               "
204 #       }
205 #
206 # then your test can be used like this:
207 #
208 #       your_test expect_(success|failure) [test_must_fail] 'git foo'
209 #
210 parse_args() {
211         test_expectation="test_$1"
212         shift
213         if test "$1" = test_must_fail
214         then
215                 full_command="test_must_fail test_terminal "
216                 shift
217         else
218                 full_command="test_terminal "
219         fi
220         cmd=$1
221         full_command="$full_command $1"
222 }
223
224 test_default_pager() {
225         parse_args "$@"
226
227         $test_expectation SIMPLEPAGER,TTY "$cmd - default pager is used by default" "
228                 sane_unset PAGER GIT_PAGER &&
229                 test_unconfig core.pager &&
230                 rm -f default_pager_used &&
231                 cat >\$less <<-\EOF &&
232                 #!/bin/sh
233                 wc >default_pager_used
234                 EOF
235                 chmod +x \$less &&
236                 (
237                         PATH=.:\$PATH &&
238                         export PATH &&
239                         $full_command
240                 ) &&
241                 test -e default_pager_used
242         "
243 }
244
245 test_PAGER_overrides() {
246         parse_args "$@"
247
248         $test_expectation TTY "$cmd - PAGER overrides default pager" "
249                 sane_unset GIT_PAGER &&
250                 test_unconfig core.pager &&
251                 rm -f PAGER_used &&
252                 PAGER='wc >PAGER_used' &&
253                 export PAGER &&
254                 $full_command &&
255                 test -e PAGER_used
256         "
257 }
258
259 test_core_pager_overrides() {
260         if_local_config=
261         used_if_wanted='overrides PAGER'
262         test_core_pager "$@"
263 }
264
265 test_local_config_ignored() {
266         if_local_config='! '
267         used_if_wanted='is not used'
268         test_core_pager "$@"
269 }
270
271 test_core_pager() {
272         parse_args "$@"
273
274         $test_expectation TTY "$cmd - repository-local core.pager setting $used_if_wanted" "
275                 sane_unset GIT_PAGER &&
276                 rm -f core.pager_used &&
277                 PAGER=wc &&
278                 export PAGER &&
279                 test_config core.pager 'wc >core.pager_used' &&
280                 $full_command &&
281                 ${if_local_config}test -e core.pager_used
282         "
283 }
284
285 test_core_pager_subdir() {
286         if_local_config=
287         used_if_wanted='overrides PAGER'
288         test_pager_subdir_helper "$@"
289 }
290
291 test_no_local_config_subdir() {
292         if_local_config='! '
293         used_if_wanted='is not used'
294         test_pager_subdir_helper "$@"
295 }
296
297 test_pager_subdir_helper() {
298         parse_args "$@"
299
300         $test_expectation TTY "$cmd - core.pager $used_if_wanted from subdirectory" "
301                 sane_unset GIT_PAGER &&
302                 rm -f core.pager_used &&
303                 rm -fr sub &&
304                 PAGER=wc &&
305                 stampname=\$(pwd)/core.pager_used &&
306                 export PAGER stampname &&
307                 test_config core.pager 'wc >\"\$stampname\"' &&
308                 mkdir sub &&
309                 (
310                         cd sub &&
311                         $full_command
312                 ) &&
313                 ${if_local_config}test -e core.pager_used
314         "
315 }
316
317 test_GIT_PAGER_overrides() {
318         parse_args "$@"
319
320         $test_expectation TTY "$cmd - GIT_PAGER overrides core.pager" "
321                 rm -f GIT_PAGER_used &&
322                 test_config core.pager wc &&
323                 GIT_PAGER='wc >GIT_PAGER_used' &&
324                 export GIT_PAGER &&
325                 $full_command &&
326                 test -e GIT_PAGER_used
327         "
328 }
329
330 test_doesnt_paginate() {
331         parse_args "$@"
332
333         $test_expectation TTY "no pager for '$cmd'" "
334                 rm -f GIT_PAGER_used &&
335                 GIT_PAGER='wc >GIT_PAGER_used' &&
336                 export GIT_PAGER &&
337                 $full_command &&
338                 ! test -e GIT_PAGER_used
339         "
340 }
341
342 test_pager_choices() {
343         test_default_pager        expect_success "$@"
344         test_PAGER_overrides      expect_success "$@"
345         test_core_pager_overrides expect_success "$@"
346         test_core_pager_subdir    expect_success "$@"
347         test_GIT_PAGER_overrides  expect_success "$@"
348 }
349
350 test_expect_success 'setup: some aliases' '
351         git config alias.aliasedlog log &&
352         git config alias.true "!true"
353 '
354
355 test_pager_choices                       'git log'
356 test_pager_choices                       'git -p log'
357 test_pager_choices                       'git aliasedlog'
358
359 test_default_pager        expect_success 'git -p aliasedlog'
360 test_PAGER_overrides      expect_success 'git -p aliasedlog'
361 test_core_pager_overrides expect_success 'git -p aliasedlog'
362 test_core_pager_subdir    expect_failure 'git -p aliasedlog'
363 test_GIT_PAGER_overrides  expect_success 'git -p aliasedlog'
364
365 test_default_pager        expect_success 'git -p true'
366 test_PAGER_overrides      expect_success 'git -p true'
367 test_core_pager_overrides expect_success 'git -p true'
368 test_core_pager_subdir    expect_failure 'git -p true'
369 test_GIT_PAGER_overrides  expect_success 'git -p true'
370
371 test_default_pager        expect_success test_must_fail 'git -p request-pull'
372 test_PAGER_overrides      expect_success test_must_fail 'git -p request-pull'
373 test_core_pager_overrides expect_success test_must_fail 'git -p request-pull'
374 test_core_pager_subdir    expect_failure test_must_fail 'git -p request-pull'
375 test_GIT_PAGER_overrides  expect_success test_must_fail 'git -p request-pull'
376
377 test_default_pager        expect_success test_must_fail 'git -p'
378 test_PAGER_overrides      expect_success test_must_fail 'git -p'
379 test_local_config_ignored expect_failure test_must_fail 'git -p'
380 test_no_local_config_subdir expect_success test_must_fail 'git -p'
381 test_GIT_PAGER_overrides  expect_success test_must_fail 'git -p'
382
383 test_doesnt_paginate      expect_failure test_must_fail 'git -p nonsense'
384
385 test_pager_choices                       'git shortlog'
386 test_expect_success 'setup: configure shortlog not to paginate' '
387         git config pager.shortlog false
388 '
389 test_doesnt_paginate      expect_success 'git shortlog'
390 test_no_local_config_subdir expect_success 'git shortlog'
391 test_default_pager        expect_success 'git -p shortlog'
392 test_core_pager_subdir    expect_success 'git -p shortlog'
393
394 test_core_pager_subdir    expect_success test_must_fail \
395                                          'git -p apply </dev/null'
396
397 test_expect_success TTY 'command-specific pager' '
398         sane_unset PAGER GIT_PAGER &&
399         echo "foo:initial" >expect &&
400         >actual &&
401         test_unconfig core.pager &&
402         test_config pager.log "sed s/^/foo:/ >actual" &&
403         test_terminal git log --format=%s -1 &&
404         test_cmp expect actual
405 '
406
407 test_expect_success TTY 'command-specific pager overrides core.pager' '
408         sane_unset PAGER GIT_PAGER &&
409         echo "foo:initial" >expect &&
410         >actual &&
411         test_config core.pager "exit 1"
412         test_config pager.log "sed s/^/foo:/ >actual" &&
413         test_terminal git log --format=%s -1 &&
414         test_cmp expect actual
415 '
416
417 test_expect_success TTY 'command-specific pager overridden by environment' '
418         GIT_PAGER="sed s/^/foo:/ >actual" && export GIT_PAGER &&
419         >actual &&
420         echo "foo:initial" >expect &&
421         test_config pager.log "exit 1" &&
422         test_terminal git log --format=%s -1 &&
423         test_cmp expect actual
424 '
425
426 test_expect_success 'setup external command' '
427         cat >git-external <<-\EOF &&
428         #!/bin/sh
429         git "$@"
430         EOF
431         chmod +x git-external
432 '
433
434 test_expect_success TTY 'command-specific pager works for external commands' '
435         sane_unset PAGER GIT_PAGER &&
436         echo "foo:initial" >expect &&
437         >actual &&
438         test_config pager.external "sed s/^/foo:/ >actual" &&
439         test_terminal git --exec-path="`pwd`" external log --format=%s -1 &&
440         test_cmp expect actual
441 '
442
443 test_expect_success TTY 'sub-commands of externals use their own pager' '
444         sane_unset PAGER GIT_PAGER &&
445         echo "foo:initial" >expect &&
446         >actual &&
447         test_config pager.log "sed s/^/foo:/ >actual" &&
448         test_terminal git --exec-path=. external log --format=%s -1 &&
449         test_cmp expect actual
450 '
451
452 test_expect_success TTY 'external command pagers override sub-commands' '
453         sane_unset PAGER GIT_PAGER &&
454         >expect &&
455         >actual &&
456         test_config pager.external false &&
457         test_config pager.log "sed s/^/log:/ >actual" &&
458         test_terminal git --exec-path=. external log --format=%s -1 &&
459         test_cmp expect actual
460 '
461
462 test_done