1#!/bin/sh
   2test_description='Test automatic use of a pager.'
   4. ./test-lib.sh
   6. "$TEST_DIRECTORY"/lib-pager.sh
   7. "$TEST_DIRECTORY"/lib-terminal.sh
   8cleanup_fail() {
  10        echo >&2 cleanup failed
  11        (exit 1)
  12}
  13test_expect_success 'setup' '
  15        sane_unset GIT_PAGER GIT_PAGER_IN_USE &&
  16        test_might_fail git config --unset core.pager &&
  17        PAGER="cat >paginated.out" &&
  19        export PAGER &&
  20        test_commit initial
  22'
  23test_expect_success TTY 'some commands use a pager' '
  25        rm -f paginated.out ||
  26        cleanup_fail &&
  27        test_terminal git log &&
  29        test -e paginated.out
  30'
  31test_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'
  46test_expect_success TTY 'some commands do not use a pager' '
  48        rm -f paginated.out ||
  49        cleanup_fail &&
  50        test_terminal git rev-list HEAD &&
  52        ! test -e paginated.out
  53'
  54test_expect_success 'no pager when stdout is a pipe' '
  56        rm -f paginated.out ||
  57        cleanup_fail &&
  58        git log | cat &&
  60        ! test -e paginated.out
  61'
  62test_expect_success 'no pager when stdout is a regular file' '
  64        rm -f paginated.out ||
  65        cleanup_fail &&
  66        git log >file &&
  68        ! test -e paginated.out
  69'
  70test_expect_success TTY 'git --paginate rev-list uses a pager' '
  72        rm -f paginated.out ||
  73        cleanup_fail &&
  74        test_terminal git --paginate rev-list HEAD &&
  76        test -e paginated.out
  77'
  78test_expect_success 'no pager even with --paginate when stdout is a pipe' '
  80        rm -f file paginated.out ||
  81        cleanup_fail &&
  82        git --paginate log | cat &&
  84        ! test -e paginated.out
  85'
  86test_expect_success TTY 'no pager with --no-pager' '
  88        rm -f paginated.out ||
  89        cleanup_fail &&
  90        test_terminal git --no-pager log &&
  92        ! test -e paginated.out
  93'
  94test_expect_success TTY 'configuration can disable pager' '
  96        rm -f paginated.out &&
  97        test_might_fail git config --unset pager.grep &&
  98        test_terminal git grep initial &&
  99        test -e paginated.out &&
 100        rm -f paginated.out &&
 102        git config pager.grep false &&
 103        test_when_finished "git config --unset pager.grep" &&
 104        test_terminal git grep initial &&
 105        ! test -e paginated.out
 106'
 107test_expect_success TTY 'git config uses a pager if configured to' '
 109        rm -f paginated.out &&
 110        git config pager.config true &&
 111        test_when_finished "git config --unset pager.config" &&
 112        test_terminal git config --list &&
 113        test -e paginated.out
 114'
 115test_expect_success TTY 'configuration can enable pager (from subdir)' '
 117        rm -f paginated.out &&
 118        mkdir -p subdir &&
 119        git config pager.bundle true &&
 120        test_when_finished "git config --unset pager.bundle" &&
 121        git bundle create test.bundle --all &&
 123        rm -f paginated.out subdir/paginated.out &&
 124        (
 125                cd subdir &&
 126                test_terminal git bundle unbundle ../test.bundle
 127        ) &&
 128        {
 129                test -e paginated.out ||
 130                test -e subdir/paginated.out
 131        }
 132'
 133# A colored commit log will begin with an appropriate ANSI escape
 135# for the first color; the text "commit" comes later.
 136colorful() {
 137        read firstline <$1
 138        ! expr "$firstline" : "[a-zA-Z]" >/dev/null
 139}
 140test_expect_success 'tests can detect color' '
 142        rm -f colorful.log colorless.log ||
 143        cleanup_fail &&
 144        git log --no-color >colorless.log &&
 146        git log --color >colorful.log &&
 147        ! colorful colorless.log &&
 148        colorful colorful.log
 149'
 150test_expect_success 'no color when stdout is a regular file' '
 152        rm -f colorless.log &&
 153        git config color.ui auto ||
 154        cleanup_fail &&
 155        git log >colorless.log &&
 157        ! colorful colorless.log
 158'
 159test_expect_success TTY 'color when writing to a pager' '
 161        rm -f paginated.out &&
 162        git config color.ui auto ||
 163        cleanup_fail &&
 164        (
 166                TERM=vt100 &&
 167                export TERM &&
 168                test_terminal git log
 169        ) &&
 170        colorful paginated.out
 171'
 172test_expect_success 'color when writing to a file intended for a pager' '
 174        rm -f colorful.log &&
 175        git config color.ui auto ||
 176        cleanup_fail &&
 177        (
 179                TERM=vt100 &&
 180                GIT_PAGER_IN_USE=true &&
 181                export TERM GIT_PAGER_IN_USE &&
 182                git log >colorful.log
 183        ) &&
 184        colorful colorful.log
 185'
 186# Use this helper to make it easy for the caller of your
 188# terminal-using function to specify whether it should fail.
 189# If you write
 190#
 191#       your_test() {
 192#               parse_args "$@"
 193#
 194#               $test_expectation "$cmd - behaves well" "
 195#                       ...
 196#                       $full_command &&
 197#                       ...
 198#               "
 199#       }
 200#
 201# then your test can be used like this:
 202#
 203#       your_test expect_(success|failure) [test_must_fail] 'git foo'
 204#
 205parse_args() {
 206        test_expectation="test_$1"
 207        shift
 208        if test "$1" = test_must_fail
 209        then
 210                full_command="test_must_fail test_terminal "
 211                shift
 212        else
 213                full_command="test_terminal "
 214        fi
 215        cmd=$1
 216        full_command="$full_command $1"
 217}
 218test_default_pager() {
 220        parse_args "$@"
 221        $test_expectation SIMPLEPAGER,TTY "$cmd - default pager is used by default" "
 223                sane_unset PAGER GIT_PAGER &&
 224                test_might_fail git config --unset core.pager &&
 225                rm -f default_pager_used ||
 226                cleanup_fail &&
 227                cat >\$less <<-\EOF &&
 229                #!/bin/sh
 230                wc >default_pager_used
 231                EOF
 232                chmod +x \$less &&
 233                (
 234                        PATH=.:\$PATH &&
 235                        export PATH &&
 236                        $full_command
 237                ) &&
 238                test -e default_pager_used
 239        "
 240}
 241test_PAGER_overrides() {
 243        parse_args "$@"
 244        $test_expectation TTY "$cmd - PAGER overrides default pager" "
 246                sane_unset GIT_PAGER &&
 247                test_might_fail git config --unset core.pager &&
 248                rm -f PAGER_used ||
 249                cleanup_fail &&
 250                PAGER='wc >PAGER_used' &&
 252                export PAGER &&
 253                $full_command &&
 254                test -e PAGER_used
 255        "
 256}
 257test_core_pager_overrides() {
 259        if_local_config=
 260        used_if_wanted='overrides PAGER'
 261        test_core_pager "$@"
 262}
 263test_local_config_ignored() {
 265        if_local_config='! '
 266        used_if_wanted='is not used'
 267        test_core_pager "$@"
 268}
 269test_core_pager() {
 271        parse_args "$@"
 272        $test_expectation TTY "$cmd - repository-local core.pager setting $used_if_wanted" "
 274                sane_unset GIT_PAGER &&
 275                rm -f core.pager_used ||
 276                cleanup_fail &&
 277                PAGER=wc &&
 279                export PAGER &&
 280                git config core.pager 'wc >core.pager_used' &&
 281                $full_command &&
 282                ${if_local_config}test -e core.pager_used
 283        "
 284}
 285test_core_pager_subdir() {
 287        if_local_config=
 288        used_if_wanted='overrides PAGER'
 289        test_pager_subdir_helper "$@"
 290}
 291test_no_local_config_subdir() {
 293        if_local_config='! '
 294        used_if_wanted='is not used'
 295        test_pager_subdir_helper "$@"
 296}
 297test_pager_subdir_helper() {
 299        parse_args "$@"
 300        $test_expectation TTY "$cmd - core.pager $used_if_wanted from subdirectory" "
 302                sane_unset GIT_PAGER &&
 303                rm -f core.pager_used &&
 304                rm -fr sub ||
 305                cleanup_fail &&
 306                PAGER=wc &&
 308                stampname=\$(pwd)/core.pager_used &&
 309                export PAGER stampname &&
 310                git config core.pager 'wc >\"\$stampname\"' &&
 311                mkdir sub &&
 312                (
 313                        cd sub &&
 314                        $full_command
 315                ) &&
 316                ${if_local_config}test -e core.pager_used
 317        "
 318}
 319test_GIT_PAGER_overrides() {
 321        parse_args "$@"
 322        $test_expectation TTY "$cmd - GIT_PAGER overrides core.pager" "
 324                rm -f GIT_PAGER_used ||
 325                cleanup_fail &&
 326                git config core.pager wc &&
 328                GIT_PAGER='wc >GIT_PAGER_used' &&
 329                export GIT_PAGER &&
 330                $full_command &&
 331                test -e GIT_PAGER_used
 332        "
 333}
 334test_doesnt_paginate() {
 336        parse_args "$@"
 337        $test_expectation TTY "no pager for '$cmd'" "
 339                rm -f GIT_PAGER_used ||
 340                cleanup_fail &&
 341                GIT_PAGER='wc >GIT_PAGER_used' &&
 343                export GIT_PAGER &&
 344                $full_command &&
 345                ! test -e GIT_PAGER_used
 346        "
 347}
 348test_pager_choices() {
 350        test_default_pager        expect_success "$@"
 351        test_PAGER_overrides      expect_success "$@"
 352        test_core_pager_overrides expect_success "$@"
 353        test_core_pager_subdir    expect_success "$@"
 354        test_GIT_PAGER_overrides  expect_success "$@"
 355}
 356test_expect_success 'setup: some aliases' '
 358        git config alias.aliasedlog log &&
 359        git config alias.true "!true"
 360'
 361test_pager_choices                       'git log'
 363test_pager_choices                       'git -p log'
 364test_pager_choices                       'git aliasedlog'
 365test_default_pager        expect_success 'git -p aliasedlog'
 367test_PAGER_overrides      expect_success 'git -p aliasedlog'
 368test_core_pager_overrides expect_success 'git -p aliasedlog'
 369test_core_pager_subdir    expect_failure 'git -p aliasedlog'
 370test_GIT_PAGER_overrides  expect_success 'git -p aliasedlog'
 371test_default_pager        expect_success 'git -p true'
 373test_PAGER_overrides      expect_success 'git -p true'
 374test_core_pager_overrides expect_success 'git -p true'
 375test_core_pager_subdir    expect_failure 'git -p true'
 376test_GIT_PAGER_overrides  expect_success 'git -p true'
 377test_default_pager        expect_success test_must_fail 'git -p request-pull'
 379test_PAGER_overrides      expect_success test_must_fail 'git -p request-pull'
 380test_core_pager_overrides expect_success test_must_fail 'git -p request-pull'
 381test_core_pager_subdir    expect_failure test_must_fail 'git -p request-pull'
 382test_GIT_PAGER_overrides  expect_success test_must_fail 'git -p request-pull'
 383test_default_pager        expect_success test_must_fail 'git -p'
 385test_PAGER_overrides      expect_success test_must_fail 'git -p'
 386test_local_config_ignored expect_failure test_must_fail 'git -p'
 387test_no_local_config_subdir expect_success test_must_fail 'git -p'
 388test_GIT_PAGER_overrides  expect_success test_must_fail 'git -p'
 389test_doesnt_paginate      expect_failure test_must_fail 'git -p nonsense'
 391test_pager_choices                       'git shortlog'
 393test_expect_success 'setup: configure shortlog not to paginate' '
 394        git config pager.shortlog false
 395'
 396test_doesnt_paginate      expect_success 'git shortlog'
 397test_no_local_config_subdir expect_success 'git shortlog'
 398test_default_pager        expect_success 'git -p shortlog'
 399test_core_pager_subdir    expect_success 'git -p shortlog'
 400test_core_pager_subdir    expect_success test_must_fail \
 402                                         'git -p apply </dev/null'
 403test_expect_success TTY 'command-specific pager' '
 405        unset PAGER GIT_PAGER;
 406        echo "foo:initial" >expect &&
 407        >actual &&
 408        git config --unset core.pager &&
 409        git config pager.log "sed s/^/foo:/ >actual" &&
 410        test_terminal git log --format=%s -1 &&
 411        test_cmp expect actual
 412'
 413test_expect_success TTY 'command-specific pager overrides core.pager' '
 415        unset PAGER GIT_PAGER;
 416        echo "foo:initial" >expect &&
 417        >actual &&
 418        git config core.pager "exit 1"
 419        git config pager.log "sed s/^/foo:/ >actual" &&
 420        test_terminal git log --format=%s -1 &&
 421        test_cmp expect actual
 422'
 423test_expect_success TTY 'command-specific pager overridden by environment' '
 425        GIT_PAGER="sed s/^/foo:/ >actual" && export GIT_PAGER &&
 426        >actual &&
 427        echo "foo:initial" >expect &&
 428        git config pager.log "exit 1" &&
 429        test_terminal git log --format=%s -1 &&
 430        test_cmp expect actual
 431'
 432test_done