blob: 753a0d524900656e23ee951f6ca56917ff73169b [file] [log] [blame]
Yegappan Lakshmanan054794c2021-06-27 12:07:49 +02001" 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()
Yegappan Lakshmananffec6dd2021-06-27 22:09:59 +02008 " The expected value of 'shellcmdflag', 'shellpipe', 'shellquote',
9 " 'shellredir', 'shellxescape', 'shellxquote' for the supported shells.
Yegappan Lakshmanan054794c2021-06-27 12:07:49 +020010 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', '"&|<>()@^', '('],
Mike Williams12795022021-06-28 20:53:58 +020027 \ ['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', '"&|<>()@^', '"'],
Yegappan Lakshmanan054794c2021-06-27 12:07:49 +020031 \ ['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
Yegappan Lakshmananffec6dd2021-06-27 22:09:59 +020043 " start a new Vim instance with 'shell' set to each of the supported shells
44 " and check the default shell option settings
Yegappan Lakshmanan054794c2021-06-27 12:07:49 +020045 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
Yegappan Lakshmananffec6dd2021-06-27 22:09:59 +020057 " Test shellescape() for each of the shells.
Yegappan Lakshmanan054794c2021-06-27 12:07:49 +020058 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'\\'' \\\\!\\%\\#'"
Mike Williams12795022021-06-28 20:53:58 +020063 elseif e[0] =~# '.*powershell$' || e[0] =~# '.*powershell.exe$'
64 let str1 = "'cmd \"arg1\" ''arg2'' !%#'"
65 let str2 = "'cmd \"arg1\" ''arg2'' \\!\\%\\#'"
Yegappan Lakshmanan054794c2021-06-27 12:07:49 +020066 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])
Yegappan Lakshmananffec6dd2021-06-27 22:09:59 +020072
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
Yegappan Lakshmanan054794c2021-06-27 12:07:49 +020083 endfor
Yegappan Lakshmananffec6dd2021-06-27 22:09:59 +020084 set shell& shellcmdflag& shellpipe& shellquote&
85 set shellredir& shellxescape& shellxquote&
Yegappan Lakshmanan054794c2021-06-27 12:07:49 +020086 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
Yegappan Lakshmananffec6dd2021-06-27 22:09:59 +0200117" Test for the 'shellescape' option
Yegappan Lakshmanan054794c2021-06-27 12:07:49 +0200118func 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
Mike Williams12795022021-06-28 20:53:58 +0200143" 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
Yegappan Lakshmanan054794c2021-06-27 12:07:49 +0200165" 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
Yegappan Lakshmananffec6dd2021-06-27 22:09:59 +0200201" 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
Yegappan Lakshmanan054794c2021-06-27 12:07:49 +0200223" vim: shiftwidth=2 sts=2 expandtab