1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
|
-- Specs for
-- - `system()`
-- - `systemlist()`
local helpers = require('test.functional.helpers')
local eq, clear, eval, feed =
helpers.eq, helpers.clear, helpers.eval, helpers.feed
local function create_file_with_nuls(name)
return function()
feed('ipart1<C-V>000part2<C-V>000part3<ESC>:w '..name..'<CR>')
end
end
local function delete_file(name)
return function()
eval("delete('"..name.."')")
end
end
-- Some tests require the xclip program and a x server.
local xclip = nil
do
if os.getenv('DISPLAY') then
local proc = io.popen('which xclip')
xclip = proc:read()
proc:close()
end
end
describe('system()', function()
before_each(clear)
it('sets the v:shell_error variable', function()
eval([[system("sh -c 'exit'")]])
eq(0, eval('v:shell_error'))
eval([[system("sh -c 'exit 1'")]])
eq(1, eval('v:shell_error'))
eval([[system("sh -c 'exit 5'")]])
eq(5, eval('v:shell_error'))
eval([[system('this-should-not-exist')]])
eq(127, eval('v:shell_error'))
end)
describe('passing no input', function()
it('returns the program output', function()
eq("echoed", eval('system("echo -n echoed")'))
end)
end)
describe('passing input', function()
it('returns the program output', function()
eq("input", eval('system("cat -", "input")'))
end)
end)
describe('passing number as input', function()
it('stringifies the input', function()
eq('1', eval('system("cat", 1)'))
end)
end)
describe('with output containing NULs', function()
local fname = 'Xtest'
setup(create_file_with_nuls(fname))
teardown(delete_file(fname))
it('replaces NULs by SOH characters', function()
eq('part1\001part2\001part3\n', eval('system("cat '..fname..'")'))
end)
end)
describe('passing list as input', function()
it('joins list items with linefeed characters', function()
eq('line1\nline2\nline3',
eval("system('cat -', ['line1', 'line2', 'line3'])"))
end)
-- Notice that NULs are converted to SOH when the data is read back. This
-- is inconsistent and is a good reason for the existence of the
-- `systemlist()` function, where input and output map to the same
-- characters(see the following tests with `systemlist()` below)
describe('with linefeed characters inside list items', function()
it('converts linefeed characters to NULs', function()
eq('l1\001p2\nline2\001a\001b\nl3',
eval([[system('cat -', ["l1\np2", "line2\na\nb", 'l3'])]]))
end)
end)
describe('with leading/trailing whitespace characters on items', function()
it('preserves whitespace, replacing linefeeds by NULs', function()
eq('line \nline2\001\n\001line3',
eval([[system('cat -', ['line ', "line2\n", "\nline3"])]]))
end)
end)
end)
if xclip then
describe("with a program that doesn't close stdout", function()
it('will exit properly after passing input', function()
eq(nil, eval([[system('xclip -i -selection clipboard', 'clip-data')]]))
eq('clip-data', eval([[system('xclip -o -selection clipboard')]]))
end)
end)
end
end)
describe('systemlist()', function()
-- behavior is similar to `system()` but it returns a list instead of a
-- string.
before_each(clear)
it('sets the v:shell_error variable', function()
eval([[systemlist("sh -c 'exit'")]])
eq(0, eval('v:shell_error'))
eval([[systemlist("sh -c 'exit 1'")]])
eq(1, eval('v:shell_error'))
eval([[systemlist("sh -c 'exit 5'")]])
eq(5, eval('v:shell_error'))
eval([[systemlist('this-should-not-exist')]])
eq(127, eval('v:shell_error'))
end)
describe('passing string with linefeed characters as input', function()
it('splits the output on linefeed characters', function()
eq({'abc', 'def', 'ghi'}, eval([[systemlist("cat -", "abc\ndef\nghi")]]))
end)
end)
describe('with output containing NULs', function()
local fname = 'Xtest'
setup(create_file_with_nuls(fname))
teardown(delete_file(fname))
it('replaces NULs by newline characters', function()
eq({'part1\npart2\npart3'}, eval('systemlist("cat '..fname..'")'))
end)
end)
describe('passing list as input', function()
it('joins list items with linefeed characters', function()
eq({'line1', 'line2', 'line3'},
eval("systemlist('cat -', ['line1', 'line2', 'line3'])"))
end)
-- Unlike `system()` which uses SOH to represent NULs, with `systemlist()`
-- input and ouput are the same
describe('with linefeed characters inside list items', function()
it('converts linefeed characters to NULs', function()
eq({'l1\np2', 'line2\na\nb', 'l3'},
eval([[systemlist('cat -', ["l1\np2", "line2\na\nb", 'l3'])]]))
end)
end)
describe('with leading/trailing whitespace characters on items', function()
it('preserves whitespace, replacing linefeeds by NULs', function()
eq({'line ', 'line2\n', '\nline3'},
eval([[systemlist('cat -', ['line ', "line2\n", "\nline3"])]]))
end)
end)
end)
if xclip then
describe("with a program that doesn't close stdout", function()
it('will exit properly after passing input', function()
eq(nil, eval(
"systemlist('xclip -i -selection clipboard', ['clip', 'data'])"))
eq({'clip', 'data'}, eval(
"systemlist('xclip -o -selection clipboard')"))
end)
end)
end
end)
|