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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
|
local Loop = require('nvim.loop')
local MsgpackStream = require('nvim.msgpack_stream')
local AsyncSession = require('nvim.async_session')
local Session = require('nvim.session')
local nvim_prog = os.getenv('NVIM_PROG') or 'build/bin/nvim'
local nvim_argv = {nvim_prog, '-u', 'NONE', '-N', '--embed'}
if os.getenv('VALGRIND') then
local log_file = os.getenv('VALGRIND_LOG') or 'valgrind-%p.log'
local valgrind_argv = {'valgrind', '-q', '--tool=memcheck',
'--leak-check=yes', '--track-origins=yes',
'--suppressions=.valgrind.supp',
'--log-file='..log_file}
if os.getenv('VALGRIND_GDB') then
table.insert(valgrind_argv, '--vgdb=yes')
table.insert(valgrind_argv, '--vgdb-error=0')
end
local len = #valgrind_argv
for i = 1, #nvim_argv do
valgrind_argv[i + len] = nvim_argv[i]
end
nvim_argv = valgrind_argv
end
local session
do
local loop = Loop.new()
local msgpack_stream = MsgpackStream.new(loop)
local async_session = AsyncSession.new(msgpack_stream)
session = Session.new(async_session)
loop:spawn(nvim_argv)
end
local function request(method, ...)
local status, rv = session:request(method, ...)
if not status then
error(rv[2])
end
return rv
end
local function nvim_command(cmd)
request('vim_command', cmd)
end
local function nvim_eval(expr)
return request('vim_eval', expr)
end
local function nvim_feed(input, mode)
mode = mode or ''
request('vim_feedkeys', input, mode)
end
local function buffer_slice(start, stop, buffer_idx)
local include_end = false
if not stop then
stop = -1
include_end = true
end
local buffer = request('vim_get_buffers')[buffer_idx or 1]
local slice = request('buffer_get_line_slice', buffer, start or 0, stop,
true, include_end)
return table.concat(slice, '\n')
end
local function nvim_replace_termcodes(input)
return request('vim_replace_termcodes', input, false, true, true )
end
local function dedent(str)
-- find minimum common indent across lines
local indent = nil
for line in str:gmatch('[^\n]+') do
local line_indent = line:match('^%s+') or ''
if indent == nil or #line_indent < #indent then
indent = line_indent
end
end
if #indent == 0 then
-- no minimum common indent
return str
end
-- create a pattern for the indent
indent = indent:gsub('%s', '%%s')
-- strip it from the first line
str = str:gsub('^'..indent, '')
-- strip it from the remaining lines
str = str:gsub('[\n]'..indent, '\n')
return str
end
local function clear()
nvim_command('call BeforeEachTest()')
end
local function feed(...)
for _, v in ipairs({...}) do
nvim_feed(nvim_replace_termcodes(dedent(v)))
end
end
local function rawfeed(...)
for _, v in ipairs({...}) do
nvim_feed(dedent(v), 'nt')
end
end
local function insert(...)
nvim_feed('i', 'nt')
rawfeed(...)
nvim_feed(nvim_replace_termcodes('<ESC>'), 'nt')
end
local function execute(...)
for _, v in ipairs({...}) do
if v:sub(1, 1) ~= '/' then
-- not a search command, prefix with colon
nvim_feed(':', 'nt')
end
nvim_feed(v, 'nt')
nvim_feed(nvim_replace_termcodes('<CR>'), 'nt')
end
end
local function eval(expr)
local status, result = pcall(function() return nvim_eval(expr) end)
if not status then
error('Failed to evaluate expression "' .. expr .. '"')
end
return result
end
local function eq(expected, actual)
return assert.are.same(expected, actual)
end
local function neq(expected, actual)
return assert.are_not.same(expected, actual)
end
local function expect(contents, first, last, buffer_index)
return eq(dedent(contents), buffer_slice(first, last, buffer_idx))
end
rawfeed([[:function BeforeEachTest()
set all&
redir => groups
silent augroup
redir END
for group in split(groups)
exe 'augroup '.group
autocmd!
augroup END
endfor
autocmd!
tabnew
let curbufnum = eval(bufnr('%'))
redir => buflist
silent ls!
redir END
let bufnums = []
for buf in split(buflist, '\n')
let bufnum = eval(split(buf, '[ u]')[0])
if bufnum != curbufnum
call add(bufnums, bufnum)
endif
endfor
if len(bufnums) > 0
exe 'silent bwipeout! '.join(bufnums, ' ')
endif
silent tabonly
for k in keys(g:)
exe 'unlet g:'.k
endfor
filetype plugin indent off
mapclear
mapclear!
abclear
comclear
endfunction
]])
return {
clear = clear,
rawfeed = rawfeed,
insert = insert,
feed = feed,
execute = execute,
eval = eval,
eq = eq,
neq = neq,
expect = expect
}
|