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