1" Test for the shell related options ('shell', 'shellcmdflag', 'shellpipe', 2" 'shellquote', 'shellredir', 'shellxescape', and 'shellxquote') 3 4source check.vim 5source shared.vim 6 7func Test_shell_options() 8 " The expected value of 'shellcmdflag', 'shellpipe', 'shellquote', 9 " 'shellredir', 'shellxescape', 'shellxquote' for the supported shells. 10 let shells = [] 11 if has('unix') 12 let shells += [['sh', '-c', '2>&1| tee', '', '>%s 2>&1', '', ''], 13 \ ['ksh', '-c', '2>&1| tee', '', '>%s 2>&1', '', ''], 14 \ ['mksh', '-c', '2>&1| tee', '', '>%s 2>&1', '', ''], 15 \ ['zsh', '-c', '2>&1| tee', '', '>%s 2>&1', '', ''], 16 \ ['zsh-beta', '-c', '2>&1| tee', '', '>%s 2>&1', '', ''], 17 \ ['bash', '-c', '2>&1| tee', '', '>%s 2>&1', '', ''], 18 \ ['fish', '-c', '2>&1| tee', '', '>%s 2>&1', '', ''], 19 \ ['ash', '-c', '2>&1| tee', '', '>%s 2>&1', '', ''], 20 \ ['dash', '-c', '2>&1| tee', '', '>%s 2>&1', '', ''], 21 \ ['csh', '-c', '|& tee', '', '>&', '', ''], 22 \ ['tcsh', '-c', '|& tee', '', '>&', '', '']] 23 endif 24 if has('win32') 25 let shells += [['cmd', '/c', '>%s 2>&1', '', '>%s 2>&1', '"&|<>()@^', ''], 26 \ ['cmd.exe', '/c', '>%s 2>&1', '', '>%s 2>&1', '"&|<>()@^', '('], 27 \ ['powershell.exe', '-Command', '2>&1 | Out-File -Encoding default', 28 \ '', '2>&1 | Out-File -Encoding default', '"&|<>()@^', '"'], 29 \ ['powershell', '-Command', '2>&1 | Out-File -Encoding default', '', 30 \ '2>&1 | Out-File -Encoding default', '"&|<>()@^', '"'], 31 \ ['sh.exe', '-c', '>%s 2>&1', '', '>%s 2>&1', '"&|<>()@^', '"'], 32 \ ['ksh.exe', '-c', '>%s 2>&1', '', '>%s 2>&1', '"&|<>()@^', '"'], 33 \ ['mksh.exe', '-c', '>%s 2>&1', '', '>%s 2>&1', '"&|<>()@^', '"'], 34 \ ['pdksh.exe', '-c', '>%s 2>&1', '', '>%s 2>&1', '"&|<>()@^', '"'], 35 \ ['zsh.exe', '-c', '>%s 2>&1', '', '>%s 2>&1', '"&|<>()@^', '"'], 36 \ ['zsh-beta.exe', '-c', '>%s 2>&1', '', '>%s 2>&1', '"&|<>()@^', '"'], 37 \ ['bash.exe', '-c', '>%s 2>&1', '', '>%s 2>&1', '"&|<>()@^', '"'], 38 \ ['dash.exe', '-c', '>%s 2>&1', '', '>%s 2>&1', '"&|<>()@^', '"'], 39 \ ['csh.exe', '-c', '>&', '', '>&', '"&|<>()@^', '"'], 40 \ ['tcsh.exe', '-c', '>&', '', '>&', '"&|<>()@^', '"']] 41 endif 42 43 " start a new Vim instance with 'shell' set to each of the supported shells 44 " and check the default shell option settings 45 let after =<< trim END 46 let l = [&shell, &shellcmdflag, &shellpipe, &shellquote] 47 let l += [&shellredir, &shellxescape, &shellxquote] 48 call writefile([json_encode(l)], 'Xtestout') 49 qall! 50 END 51 for e in shells 52 if RunVim([], after, '--cmd "set shell=' .. e[0] .. '"') 53 call assert_equal(e, json_decode(readfile('Xtestout')[0])) 54 endif 55 endfor 56 57 " Test shellescape() for each of the shells. 58 for e in shells 59 exe 'set shell=' .. e[0] 60 if e[0] =~# '.*csh$' || e[0] =~# '.*csh.exe$' 61 let str1 = "'cmd \"arg1\" '\\''arg2'\\'' \\!%#'" 62 let str2 = "'cmd \"arg1\" '\\''arg2'\\'' \\\\!\\%\\#'" 63 elseif e[0] =~# '.*powershell$' || e[0] =~# '.*powershell.exe$' 64 let str1 = "'cmd \"arg1\" ''arg2'' !%#'" 65 let str2 = "'cmd \"arg1\" ''arg2'' \\!\\%\\#'" 66 else 67 let str1 = "'cmd \"arg1\" '\\''arg2'\\'' !%#'" 68 let str2 = "'cmd \"arg1\" '\\''arg2'\\'' \\!\\%\\#'" 69 endif 70 call assert_equal(str1, shellescape("cmd \"arg1\" 'arg2' !%#"), e[0]) 71 call assert_equal(str2, shellescape("cmd \"arg1\" 'arg2' !%#", 1), e[0]) 72 73 " Try running an external command with the shell. 74 if executable(e[0]) 75 " set the shell options for the current 'shell' 76 let [&shellcmdflag, &shellpipe, &shellquote, &shellredir, 77 \ &shellxescape, &shellxquote] = e[1:6] 78 new 79 r !echo hello 80 call assert_equal('hello', substitute(getline(2), '\W', '', 'g'), e[0]) 81 bwipe! 82 endif 83 endfor 84 set shell& shellcmdflag& shellpipe& shellquote& 85 set shellredir& shellxescape& shellxquote& 86 call delete('Xtestout') 87endfunc 88 89" Test for the 'shell' option 90func Test_shell() 91 CheckUnix 92 let save_shell = &shell 93 set shell= 94 let caught_e91 = 0 95 try 96 shell 97 catch /E91:/ 98 let caught_e91 = 1 99 endtry 100 call assert_equal(1, caught_e91) 101 let &shell = save_shell 102endfunc 103 104" Test for the 'shellquote' option 105func Test_shellquote() 106 CheckUnix 107 set shellquote=# 108 set verbose=20 109 redir => v 110 silent! !echo Hello 111 redir END 112 set verbose& 113 set shellquote& 114 call assert_match(': "#echo Hello#"', v) 115endfunc 116 117" Test for the 'shellescape' option 118func Test_shellescape() 119 let save_shell = &shell 120 set shell=bash 121 call assert_equal("'text'", shellescape('text')) 122 call assert_equal("'te\"xt'", 'te"xt'->shellescape()) 123 call assert_equal("'te'\\''xt'", shellescape("te'xt")) 124 125 call assert_equal("'te%xt'", shellescape("te%xt")) 126 call assert_equal("'te\\%xt'", shellescape("te%xt", 1)) 127 call assert_equal("'te#xt'", shellescape("te#xt")) 128 call assert_equal("'te\\#xt'", shellescape("te#xt", 1)) 129 call assert_equal("'te!xt'", shellescape("te!xt")) 130 call assert_equal("'te\\!xt'", shellescape("te!xt", 1)) 131 132 call assert_equal("'te\nxt'", shellescape("te\nxt")) 133 call assert_equal("'te\\\nxt'", shellescape("te\nxt", 1)) 134 set shell=tcsh 135 call assert_equal("'te\\!xt'", shellescape("te!xt")) 136 call assert_equal("'te\\\\!xt'", shellescape("te!xt", 1)) 137 call assert_equal("'te\\\nxt'", shellescape("te\nxt")) 138 call assert_equal("'te\\\\\nxt'", shellescape("te\nxt", 1)) 139 140 let &shell = save_shell 141endfunc 142 143" Test for 'shellslash' 144func Test_shellslash() 145 CheckOption shellslash 146 let save_shellslash = &shellslash 147 " The shell and cmdflag, and expected slash in tempname with shellslash set or 148 " unset. The assert checks the file separator before the leafname. 149 " ".*\\\\[^\\\\]*$" 150 let shells = [['cmd', '/c', '\\', '/'], 151 \ ['powershell', '-Command', '\\', '/'], 152 \ ['sh', '-c', '/', '/']] 153 for e in shells 154 exe 'set shell=' .. e[0] .. ' | set shellcmdflag=' .. e[1] 155 set noshellslash 156 let file = tempname() 157 call assert_match('^.\+' .. e[2] .. '[^' .. e[2] .. ']\+$', file, e[0] .. ' ' .. e[1] .. ' nossl') 158 set shellslash 159 let file = tempname() 160 call assert_match('^.\+' .. e[3] .. '[^' .. e[3] .. ']\+$', file, e[0] .. ' ' .. e[1] .. ' ssl') 161 endfor 162 let &shellslash = save_shellslash 163endfunc 164 165" Test for 'shellxquote' 166func Test_shellxquote() 167 CheckUnix 168 169 let save_shell = &shell 170 let save_sxq = &shellxquote 171 let save_sxe = &shellxescape 172 173 call writefile(['#!/bin/sh', 'echo "Cmd: [$*]" > Xlog'], 'Xtestshell') 174 call setfperm('Xtestshell', "r-x------") 175 set shell=./Xtestshell 176 177 set shellxquote=\\" 178 call feedkeys(":!pwd\<CR>\<CR>", 'xt') 179 call assert_equal(['Cmd: [-c "pwd"]'], readfile('Xlog')) 180 181 set shellxquote=( 182 call feedkeys(":!pwd\<CR>\<CR>", 'xt') 183 call assert_equal(['Cmd: [-c (pwd)]'], readfile('Xlog')) 184 185 set shellxquote=\\"( 186 call feedkeys(":!pwd\<CR>\<CR>", 'xt') 187 call assert_equal(['Cmd: [-c "(pwd)"]'], readfile('Xlog')) 188 189 set shellxescape=\"&<<()@^ 190 set shellxquote=( 191 call feedkeys(":!pwd\"&<<{}@^\<CR>\<CR>", 'xt') 192 call assert_equal(['Cmd: [-c (pwd^"^&^<^<{}^@^^)]'], readfile('Xlog')) 193 194 let &shell = save_shell 195 let &shellxquote = save_sxq 196 let &shellxescape = save_sxe 197 call delete('Xtestshell') 198 call delete('Xlog') 199endfunc 200 201" Test for using the shell set in the $SHELL environment variable 202func Test_set_shell() 203 let after =<< trim [CODE] 204 call writefile([&shell], "Xtestout") 205 quit! 206 [CODE] 207 208 if has('win32') 209 let $SHELL = 'C:\with space\cmd.exe' 210 let expected = '"C:\with space\cmd.exe"' 211 else 212 let $SHELL = '/bin/with space/sh' 213 let expected = '/bin/with\ space/sh' 214 endif 215 216 if RunVimPiped([], after, '', '') 217 let lines = readfile('Xtestout') 218 call assert_equal(expected, lines[0]) 219 endif 220 call delete('Xtestout') 221endfunc 222 223" vim: shiftwidth=2 sts=2 expandtab 224