view src/testdir/test_shell.vim @ 27970:212c5894b8b1 v8.2.4510

patch 8.2.4510: Vim9: shortening commands leads to confusing script Commit: https://github.com/vim/vim/commit/204852ae2adfdde10c656ca7f14e5b4207a69172 Author: Bram Moolenaar <Bram@vim.org> Date: Sat Mar 5 12:56:44 2022 +0000 patch 8.2.4510: Vim9: shortening commands leads to confusing script Problem: Vim9: shortening commands leads to confusing script. Solution: In Vim9 script require at least ":cont" for ":continue", "const" instead of "cons", "break" instead of "brea", "catch" instead of "cat", "else" instead of "el" "elseif" instead of "elsei" "endfor" instead of "endfo" "endif" instead of "en" "endtry" instead of "endt", "finally" instead of "fina", "throw" instead of "th", "while" instead of "wh".
author Bram Moolenaar <Bram@vim.org>
date Sat, 05 Mar 2022 14:00:03 +0100
parents 454cbc872368
children 008808e60963
line wrap: on
line source

" Test for the shell related options ('shell', 'shellcmdflag', 'shellpipe',
" 'shellquote', 'shellredir', 'shellxescape', and 'shellxquote')

source check.vim
source shared.vim

func Test_shell_options()
  " The expected value of 'shellcmdflag', 'shellpipe', 'shellquote',
  " 'shellredir', 'shellxescape', 'shellxquote' for the supported shells.
  let shells = []
  if has('unix')
    let shells += [['sh', '-c', '2>&1| tee', '', '>%s 2>&1', '', ''],
          \ ['ksh', '-c', '2>&1| tee', '', '>%s 2>&1', '', ''],
          \ ['mksh', '-c', '2>&1| tee', '', '>%s 2>&1', '', ''],
          \ ['zsh', '-c', '2>&1| tee', '', '>%s 2>&1', '', ''],
          \ ['zsh-beta', '-c', '2>&1| tee', '', '>%s 2>&1', '', ''],
          \ ['bash', '-c', '2>&1| tee', '', '>%s 2>&1', '', ''],
          \ ['fish', '-c', '2>&1| tee', '', '>%s 2>&1', '', ''],
          \ ['ash', '-c', '2>&1| tee', '', '>%s 2>&1', '', ''],
          \ ['dash', '-c', '2>&1| tee', '', '>%s 2>&1', '', ''],
          \ ['csh', '-c', '|& tee', '', '>&', '', ''],
          \ ['tcsh', '-c', '|& tee', '', '>&', '', ''],
          \ ['pwsh', '-c', '>%s 2>&1', '', '>%s 2>&1', '', '']]
  endif
  if has('win32')
    let shells += [['cmd', '/c', '>%s 2>&1', '', '>%s 2>&1', '"&|<>()@^', ''],
          \ ['cmd.exe', '/c', '>%s 2>&1', '', '>%s 2>&1', '"&|<>()@^', '('],
          \ ['powershell.exe', '-Command', '2>&1 | Out-File -Encoding default',
          \           '', '2>&1 | Out-File -Encoding default', '"&|<>()@^', '"'],
          \ ['powershell', '-Command', '2>&1 | Out-File -Encoding default', '',
          \               '2>&1 | Out-File -Encoding default', '"&|<>()@^', '"'],
          \ ['pwsh.exe', '-c', '>%s 2>&1', '', '>%s 2>&1', '"&|<>()@^', '"'],
          \ ['pwsh', '-c', '>%s 2>&1', '', '>%s 2>&1', '"&|<>()@^', '"'],
          \ ['sh.exe', '-c', '>%s 2>&1', '', '>%s 2>&1', '"&|<>()@^', '"'],
          \ ['ksh.exe', '-c', '>%s 2>&1', '', '>%s 2>&1', '"&|<>()@^', '"'],
          \ ['mksh.exe', '-c', '>%s 2>&1', '', '>%s 2>&1', '"&|<>()@^', '"'],
          \ ['pdksh.exe', '-c', '>%s 2>&1', '', '>%s 2>&1', '"&|<>()@^', '"'],
          \ ['zsh.exe', '-c', '>%s 2>&1', '', '>%s 2>&1', '"&|<>()@^', '"'],
          \ ['zsh-beta.exe', '-c', '>%s 2>&1', '', '>%s 2>&1', '"&|<>()@^', '"'],
          \ ['bash.exe', '-c', '>%s 2>&1', '', '>%s 2>&1', '"&|<>()@^', '"'],
          \ ['dash.exe', '-c', '>%s 2>&1', '', '>%s 2>&1', '"&|<>()@^', '"'],
          \ ['csh.exe', '-c', '>&', '', '>&', '"&|<>()@^', '"'],
          \ ['tcsh.exe', '-c', '>&', '', '>&', '"&|<>()@^', '"']]
  endif

  " start a new Vim instance with 'shell' set to each of the supported shells
  " and check the default shell option settings
  let after =<< trim END
    let l = [&shell, &shellcmdflag, &shellpipe, &shellquote]
    let l += [&shellredir, &shellxescape, &shellxquote]
    call writefile([json_encode(l)], 'Xtestout')
    qall!
  END
  for e in shells
    if RunVim([], after, '--cmd "set shell=' .. e[0] .. '"')
      call assert_equal(e, json_decode(readfile('Xtestout')[0]))
    endif
  endfor

  " Test shellescape() for each of the shells.
  for e in shells
    exe 'set shell=' .. e[0]
    if e[0] =~# '.*csh$' || e[0] =~# '.*csh.exe$'
      let str1 = "'cmd \"arg1\" '\\''arg2'\\'' \\!%# \\'\\'' \\\\! \\% \\#'"
      let str2 = "'cmd \"arg1\" '\\''arg2'\\'' \\\\!\\%\\# \\'\\'' \\\\\\! \\\\% \\\\#'"
    elseif e[0] =~# '.*powershell$' || e[0] =~# '.*powershell.exe$'
          \ || e[0] =~# '.*pwsh$' || e[0] =~# '.*pwsh.exe$'
      let str1 = "'cmd \"arg1\" ''arg2'' !%# \\'' \\! \\% \\#'"
      let str2 = "'cmd \"arg1\" ''arg2'' \\!\\%\\# \\'' \\\\! \\\\% \\\\#'"
    elseif e[0] =~# '.*fish$' || e[0] =~# '.*fish.exe$'
      let str1 = "'cmd \"arg1\" '\\''arg2'\\'' !%# \\\\'\\'' \\\\! \\\\% \\\\#'"
      let str2 = "'cmd \"arg1\" '\\''arg2'\\'' \\!\\%\\# \\\\'\\'' \\\\\\! \\\\\\% \\\\\\#'"
    else
      let str1 = "'cmd \"arg1\" '\\''arg2'\\'' !%# \\'\\'' \\! \\% \\#'"
      let str2 = "'cmd \"arg1\" '\\''arg2'\\'' \\!\\%\\# \\'\\'' \\\\! \\\\% \\\\#'"
    endif
    call assert_equal(str1, shellescape("cmd \"arg1\" 'arg2' !%# \\' \\! \\% \\#"), e[0])
    call assert_equal(str2, shellescape("cmd \"arg1\" 'arg2' !%# \\' \\! \\% \\#", 1), e[0])

    " Try running an external command with the shell.
    if executable(e[0])
      " set the shell options for the current 'shell'
      let [&shellcmdflag, &shellpipe, &shellquote, &shellredir,
            \ &shellxescape, &shellxquote] = e[1:6]
      new
      try
        r !echo hello
        call assert_equal('hello', substitute(getline(2), '\W', '', 'g'), e[0])
      catch
        call assert_report('Failed to run shell command, shell: ' .. e[0]
              \ .. ', caught ' .. v:exception)
      finally
        bwipe!
      endtry
    endif
  endfor
  set shell& shellcmdflag& shellpipe& shellquote&
  set shellredir& shellxescape& shellxquote&
  call delete('Xtestout')
endfunc

" Test for the 'shell' option
func Test_shell()
  CheckUnix
  let save_shell = &shell
  set shell=
  let caught_e91 = 0
  try
    shell
  catch /E91:/
    let caught_e91 = 1
  endtry
  call assert_equal(1, caught_e91)
  let &shell = save_shell
endfunc

" Test for the 'shellquote' option
func Test_shellquote()
  CheckUnix
  set shellquote=#
  set verbose=20
  redir => v
  silent! !echo Hello
  redir END
  set verbose&
  set shellquote&
  call assert_match(': "#echo Hello#"', v)
endfunc

" Test for the 'shellescape' option
func Test_shellescape()
  let save_shell = &shell
  set shell=bash
  call assert_equal("'text'", shellescape('text'))
  call assert_equal("'te\"xt'", 'te"xt'->shellescape())
  call assert_equal("'te'\\''xt'", shellescape("te'xt"))

  call assert_equal("'te%xt'", shellescape("te%xt"))
  call assert_equal("'te\\%xt'", shellescape("te%xt", 1))
  call assert_equal("'te#xt'", shellescape("te#xt"))
  call assert_equal("'te\\#xt'", shellescape("te#xt", 1))
  call assert_equal("'te!xt'", shellescape("te!xt"))
  call assert_equal("'te\\!xt'", shellescape("te!xt", 1))

  call assert_equal("'te\nxt'", shellescape("te\nxt"))
  call assert_equal("'te\\\nxt'", shellescape("te\nxt", 1))
  set shell=tcsh
  call assert_equal("'te\\!xt'", shellescape("te!xt"))
  call assert_equal("'te\\\\!xt'", shellescape("te!xt", 1))
  call assert_equal("'te\\\nxt'", shellescape("te\nxt"))
  call assert_equal("'te\\\\\nxt'", shellescape("te\nxt", 1))

  let &shell = save_shell
endfunc

" Test for 'shellslash'
func Test_shellslash()
  CheckOption shellslash
  let save_shellslash = &shellslash
  " The shell and cmdflag, and expected slash in tempname with shellslash set or
  " unset.  The assert checks the file separator before the leafname.
  " ".*\\\\[^\\\\]*$"
  let shells = [['cmd', '/c', '\\', '/'],
        \ ['powershell', '-Command', '\\', '/'],
        \ ['pwsh', '-Command', '\\', '/'],
        \ ['pwsh', '-c', '\\', '/'],
        \ ['sh', '-c', '/', '/']]
  for e in shells
    exe 'set shell=' .. e[0] .. ' | set shellcmdflag=' .. e[1]
    set noshellslash
    let file = tempname()
    call assert_match('^.\+' .. e[2] .. '[^' .. e[2] .. ']\+$', file, e[0] .. ' ' .. e[1] .. ' nossl')
    set shellslash
    let file = tempname()
    call assert_match('^.\+' .. e[3] .. '[^' .. e[3] .. ']\+$', file, e[0] .. ' ' .. e[1] .. ' ssl')
  endfor
  let &shellslash = save_shellslash
endfunc

" Test for 'shellxquote'
func Test_shellxquote()
  CheckUnix

  let save_shell = &shell
  let save_sxq = &shellxquote
  let save_sxe = &shellxescape

  call writefile(['#!/bin/sh', 'echo "Cmd: [$*]" > Xlog'], 'Xtestshell')
  call setfperm('Xtestshell', "r-x------")
  set shell=./Xtestshell

  set shellxquote=\\"
  call feedkeys(":!pwd\<CR>\<CR>", 'xt')
  call assert_equal(['Cmd: [-c "pwd"]'], readfile('Xlog'))

  set shellxquote=(
  call feedkeys(":!pwd\<CR>\<CR>", 'xt')
  call assert_equal(['Cmd: [-c (pwd)]'], readfile('Xlog'))

  set shellxquote=\\"(
  call feedkeys(":!pwd\<CR>\<CR>", 'xt')
  call assert_equal(['Cmd: [-c "(pwd)"]'], readfile('Xlog'))

  set shellxescape=\"&<<()@^
  set shellxquote=(
  call feedkeys(":!pwd\"&<<{}@^\<CR>\<CR>", 'xt')
  call assert_equal(['Cmd: [-c (pwd^"^&^<^<{}^@^^)]'], readfile('Xlog'))

  let &shell = save_shell
  let &shellxquote = save_sxq
  let &shellxescape = save_sxe
  call delete('Xtestshell')
  call delete('Xlog')
endfunc

" Test for using the shell set in the $SHELL environment variable
func Test_set_shell()
  let after =<< trim [CODE]
    call writefile([&shell], "Xtestout")
    quit!
  [CODE]

  if has('win32')
    let $SHELL = 'C:\with space\cmd.exe'
    let expected = '"C:\with space\cmd.exe"'
  else
    let $SHELL = '/bin/with space/sh'
    let expected = '/bin/with\ space/sh'
  endif

  if RunVimPiped([], after, '', '')
    let lines = readfile('Xtestout')
    call assert_equal(expected, lines[0])
  endif
  call delete('Xtestout')
endfunc

" vim: shiftwidth=2 sts=2 expandtab