12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061 |
- local protocol = require 'vim.lsp.protocol'
- -- Logs to $NVIM_LOG_FILE.
- --
- -- TODO(justinmk): remove after https://github.com/neovim/neovim/pull/7062
- local function log(loglevel, area, msg)
- vim.fn.writefile({ string.format('%s %s: %s', loglevel, area, msg) }, vim.env.NVIM_LOG_FILE, 'a')
- end
- local function message_parts(sep, ...)
- local parts = {}
- for i = 1, select('#', ...) do
- local arg = select(i, ...)
- if arg ~= nil then
- table.insert(parts, arg)
- end
- end
- return table.concat(parts, sep)
- end
- -- Assert utility methods
- local function assert_eq(a, b, ...)
- if not vim.deep_equal(a, b) then
- error(
- message_parts(
- ': ',
- ...,
- 'assert_eq failed',
- string.format(
- 'left == %q, right == %q',
- table.concat(vim.split(vim.inspect(a), '\n'), ''),
- table.concat(vim.split(vim.inspect(b), '\n'), '')
- )
- )
- )
- end
- end
- local function format_message_with_content_length(encoded_message)
- return table.concat {
- 'Content-Length: ',
- tostring(#encoded_message),
- '\r\n\r\n',
- encoded_message,
- }
- end
- local function read_message()
- local line = io.read('*l')
- local length = line:lower():match('content%-length:%s*(%d+)')
- return vim.json.decode(io.read(2 + length):sub(2))
- end
- local function send(payload)
- io.stdout:write(format_message_with_content_length(vim.json.encode(payload)))
- end
- local function respond(id, err, result)
- assert(type(id) == 'number', 'id must be a number')
- send { jsonrpc = '2.0', id = id, error = err, result = result }
- end
- local function notify(method, params)
- assert(type(method) == 'string', 'method must be a string')
- send { method = method, params = params or {} }
- end
- local function expect_notification(method, params, ...)
- local message = read_message()
- assert_eq(method, message.method, ..., 'expect_notification', 'method')
- if params then
- assert_eq(params, message.params, ..., 'expect_notification', method, 'params')
- assert_eq(
- { jsonrpc = '2.0', method = method, params = params },
- message,
- ...,
- 'expect_notification',
- 'message'
- )
- end
- end
- local function expect_request(method, handler, ...)
- local req = read_message()
- assert_eq(method, req.method, ..., 'expect_request', 'method')
- local err, result = handler(req.params)
- respond(req.id, err, result)
- end
- io.stderr:setvbuf('no')
- local function skeleton(config)
- local on_init = assert(config.on_init)
- local body = assert(config.body)
- expect_request('initialize', function(params)
- return nil, on_init(params)
- end)
- expect_notification('initialized', {})
- body()
- expect_request('shutdown', function()
- return nil, {}
- end)
- expect_notification('exit', nil)
- end
- -- The actual tests.
- local tests = {}
- function tests.basic_init()
- skeleton {
- on_init = function(params)
- assert_eq(params.workDoneToken, '1')
- return {
- capabilities = {
- textDocumentSync = protocol.TextDocumentSyncKind.None,
- },
- }
- end,
- body = function()
- notify('test')
- end,
- }
- end
- function tests.basic_init_did_change_configuration()
- skeleton({
- on_init = function(_)
- return {
- capabilities = {},
- }
- end,
- body = function()
- expect_notification('workspace/didChangeConfiguration', { settings = { dummy = 1 } })
- end,
- })
- end
- function tests.check_workspace_configuration()
- skeleton {
- on_init = function(_params)
- return { capabilities = {} }
- end,
- body = function()
- notify('start')
- notify('workspace/configuration', {
- items = {
- { section = 'testSetting1' },
- { section = 'testSetting2' },
- { section = 'test.Setting3' },
- { section = 'test.Setting4' },
- },
- })
- expect_notification('workspace/configuration', { true, false, 'nested', vim.NIL })
- notify('shutdown')
- end,
- }
- end
- function tests.prepare_rename_nil()
- skeleton {
- on_init = function()
- return {
- capabilities = {
- renameProvider = {
- prepareProvider = true,
- },
- },
- }
- end,
- body = function()
- notify('start')
- expect_request('textDocument/prepareRename', function()
- return nil, nil
- end)
- notify('shutdown')
- end,
- }
- end
- function tests.prepare_rename_placeholder()
- skeleton {
- on_init = function()
- return {
- capabilities = {
- renameProvider = {
- prepareProvider = true,
- },
- },
- }
- end,
- body = function()
- notify('start')
- expect_request('textDocument/prepareRename', function()
- return nil, { placeholder = 'placeholder' }
- end)
- expect_request('textDocument/rename', function(params)
- assert_eq(params.newName, 'renameto')
- return nil, nil
- end)
- notify('shutdown')
- end,
- }
- end
- function tests.prepare_rename_range()
- skeleton {
- on_init = function()
- return {
- capabilities = {
- renameProvider = {
- prepareProvider = true,
- },
- },
- }
- end,
- body = function()
- notify('start')
- expect_request('textDocument/prepareRename', function()
- return nil,
- {
- start = { line = 1, character = 8 },
- ['end'] = { line = 1, character = 12 },
- }
- end)
- expect_request('textDocument/rename', function(params)
- assert_eq(params.newName, 'renameto')
- return nil, nil
- end)
- notify('shutdown')
- end,
- }
- end
- function tests.prepare_rename_error()
- skeleton {
- on_init = function()
- return {
- capabilities = {
- renameProvider = {
- prepareProvider = true,
- },
- },
- }
- end,
- body = function()
- notify('start')
- expect_request('textDocument/prepareRename', function()
- return {}, nil
- end)
- notify('shutdown')
- end,
- }
- end
- function tests.basic_check_capabilities()
- skeleton {
- on_init = function(params)
- local expected_capabilities = protocol.make_client_capabilities()
- assert_eq(params.capabilities, expected_capabilities)
- return {
- capabilities = {
- textDocumentSync = protocol.TextDocumentSyncKind.Full,
- codeLensProvider = false,
- },
- }
- end,
- body = function() end,
- }
- end
- function tests.text_document_save_did_open()
- skeleton {
- on_init = function()
- return {
- capabilities = {
- textDocumentSync = {
- save = true,
- },
- },
- }
- end,
- body = function()
- notify('start')
- expect_notification('textDocument/didClose')
- expect_notification('textDocument/didOpen')
- expect_notification('textDocument/didSave')
- notify('shutdown')
- end,
- }
- end
- function tests.text_document_sync_save_bool()
- skeleton {
- on_init = function()
- return {
- capabilities = {
- textDocumentSync = {
- save = true,
- },
- },
- }
- end,
- body = function()
- notify('start')
- expect_notification('textDocument/didSave', { textDocument = { uri = 'file://' } })
- notify('shutdown')
- end,
- }
- end
- function tests.text_document_sync_save_includeText()
- skeleton {
- on_init = function()
- return {
- capabilities = {
- textDocumentSync = {
- save = {
- includeText = true,
- },
- },
- },
- }
- end,
- body = function()
- notify('start')
- expect_notification('textDocument/didSave', {
- textDocument = {
- uri = 'file://',
- },
- text = 'help me\n',
- })
- notify('shutdown')
- end,
- }
- end
- function tests.capabilities_for_client_supports_method()
- skeleton {
- on_init = function(params)
- local expected_capabilities = protocol.make_client_capabilities()
- assert_eq(params.capabilities, expected_capabilities)
- return {
- capabilities = {
- textDocumentSync = protocol.TextDocumentSyncKind.Full,
- completionProvider = true,
- hoverProvider = true,
- renameProvider = false,
- definitionProvider = false,
- referencesProvider = false,
- codeLensProvider = { resolveProvider = true },
- },
- }
- end,
- body = function() end,
- }
- end
- function tests.check_forward_request_cancelled()
- skeleton {
- on_init = function(_)
- return { capabilities = {} }
- end,
- body = function()
- expect_request('error_code_test', function()
- return { code = -32800 }, nil, { method = 'error_code_test', client_id = 1 }
- end)
- notify('finish')
- end,
- }
- end
- function tests.check_forward_content_modified()
- skeleton {
- on_init = function(_)
- return { capabilities = {} }
- end,
- body = function()
- expect_request('error_code_test', function()
- return { code = -32801 }, nil, { method = 'error_code_test', client_id = 1 }
- end)
- expect_notification('finish')
- notify('finish')
- end,
- }
- end
- function tests.check_forward_server_cancelled()
- skeleton {
- on_init = function()
- return { capabilities = {} }
- end,
- body = function()
- expect_request('error_code_test', function()
- return { code = -32802 }, nil, { method = 'error_code_test', client_id = 1 }
- end)
- expect_notification('finish')
- notify('finish')
- end,
- }
- end
- function tests.check_pending_request_tracked()
- skeleton {
- on_init = function(_)
- return { capabilities = {} }
- end,
- body = function()
- local msg = read_message()
- assert_eq('slow_request', msg.method)
- expect_notification('release')
- respond(msg.id, nil, {})
- expect_notification('finish')
- notify('finish')
- end,
- }
- end
- function tests.check_cancel_request_tracked()
- skeleton {
- on_init = function(_)
- return { capabilities = {} }
- end,
- body = function()
- local msg = read_message()
- assert_eq('slow_request', msg.method)
- expect_notification('$/cancelRequest', { id = msg.id })
- expect_notification('release')
- respond(msg.id, { code = -32800 }, nil)
- notify('finish')
- end,
- }
- end
- function tests.check_tracked_requests_cleared()
- skeleton {
- on_init = function(_)
- return { capabilities = {} }
- end,
- body = function()
- local msg = read_message()
- assert_eq('slow_request', msg.method)
- expect_notification('$/cancelRequest', { id = msg.id })
- expect_notification('release')
- respond(msg.id, nil, {})
- expect_notification('finish')
- notify('finish')
- end,
- }
- end
- function tests.basic_finish()
- skeleton {
- on_init = function(params)
- local expected_capabilities = protocol.make_client_capabilities()
- assert_eq(params.capabilities, expected_capabilities)
- return {
- capabilities = {
- textDocumentSync = protocol.TextDocumentSyncKind.Full,
- },
- }
- end,
- body = function()
- expect_notification('finish')
- notify('finish')
- end,
- }
- end
- function tests.basic_check_buffer_open()
- skeleton {
- on_init = function(params)
- local expected_capabilities = protocol.make_client_capabilities()
- assert_eq(params.capabilities, expected_capabilities)
- return {
- capabilities = {
- textDocumentSync = protocol.TextDocumentSyncKind.Full,
- },
- }
- end,
- body = function()
- notify('start')
- expect_notification('textDocument/didOpen', {
- textDocument = {
- languageId = '',
- text = table.concat({ 'testing', '123' }, '\n') .. '\n',
- uri = 'file://',
- version = 0,
- },
- })
- expect_notification('finish')
- notify('finish')
- end,
- }
- end
- function tests.basic_check_buffer_open_and_change()
- skeleton {
- on_init = function(params)
- local expected_capabilities = protocol.make_client_capabilities()
- assert_eq(params.capabilities, expected_capabilities)
- return {
- capabilities = {
- textDocumentSync = protocol.TextDocumentSyncKind.Full,
- },
- }
- end,
- body = function()
- notify('start')
- expect_notification('textDocument/didOpen', {
- textDocument = {
- languageId = '',
- text = table.concat({ 'testing', '123' }, '\n') .. '\n',
- uri = 'file://',
- version = 0,
- },
- })
- expect_notification('textDocument/didChange', {
- textDocument = {
- uri = 'file://',
- version = 3,
- },
- contentChanges = {
- { text = table.concat({ 'testing', 'boop' }, '\n') .. '\n' },
- },
- })
- expect_notification('finish')
- notify('finish')
- end,
- }
- end
- function tests.basic_check_buffer_open_and_change_noeol()
- skeleton {
- on_init = function(params)
- local expected_capabilities = protocol.make_client_capabilities()
- assert_eq(params.capabilities, expected_capabilities)
- return {
- capabilities = {
- textDocumentSync = protocol.TextDocumentSyncKind.Full,
- },
- }
- end,
- body = function()
- notify('start')
- expect_notification('textDocument/didOpen', {
- textDocument = {
- languageId = '',
- text = table.concat({ 'testing', '123' }, '\n'),
- uri = 'file://',
- version = 0,
- },
- })
- expect_notification('textDocument/didChange', {
- textDocument = {
- uri = 'file://',
- version = 3,
- },
- contentChanges = {
- { text = table.concat({ 'testing', 'boop' }, '\n') },
- },
- })
- expect_notification('finish')
- notify('finish')
- end,
- }
- end
- function tests.basic_check_buffer_open_and_change_multi()
- skeleton {
- on_init = function(params)
- local expected_capabilities = protocol.make_client_capabilities()
- assert_eq(params.capabilities, expected_capabilities)
- return {
- capabilities = {
- textDocumentSync = protocol.TextDocumentSyncKind.Full,
- },
- }
- end,
- body = function()
- notify('start')
- expect_notification('textDocument/didOpen', {
- textDocument = {
- languageId = '',
- text = table.concat({ 'testing', '123' }, '\n') .. '\n',
- uri = 'file://',
- version = 0,
- },
- })
- expect_notification('textDocument/didChange', {
- textDocument = {
- uri = 'file://',
- version = 3,
- },
- contentChanges = {
- { text = table.concat({ 'testing', '321' }, '\n') .. '\n' },
- },
- })
- expect_notification('textDocument/didChange', {
- textDocument = {
- uri = 'file://',
- version = 4,
- },
- contentChanges = {
- { text = table.concat({ 'testing', 'boop' }, '\n') .. '\n' },
- },
- })
- expect_notification('finish')
- notify('finish')
- end,
- }
- end
- function tests.basic_check_buffer_open_and_change_multi_and_close()
- skeleton {
- on_init = function(params)
- local expected_capabilities = protocol.make_client_capabilities()
- assert_eq(params.capabilities, expected_capabilities)
- return {
- capabilities = {
- textDocumentSync = protocol.TextDocumentSyncKind.Full,
- },
- }
- end,
- body = function()
- notify('start')
- expect_notification('textDocument/didOpen', {
- textDocument = {
- languageId = '',
- text = table.concat({ 'testing', '123' }, '\n') .. '\n',
- uri = 'file://',
- version = 0,
- },
- })
- expect_notification('textDocument/didChange', {
- textDocument = {
- uri = 'file://',
- version = 3,
- },
- contentChanges = {
- { text = table.concat({ 'testing', '321' }, '\n') .. '\n' },
- },
- })
- expect_notification('textDocument/didChange', {
- textDocument = {
- uri = 'file://',
- version = 4,
- },
- contentChanges = {
- { text = table.concat({ 'testing', 'boop' }, '\n') .. '\n' },
- },
- })
- expect_notification('textDocument/didClose', {
- textDocument = {
- uri = 'file://',
- },
- })
- expect_notification('finish')
- notify('finish')
- end,
- }
- end
- function tests.basic_check_buffer_open_and_change_incremental()
- skeleton {
- on_init = function(params)
- local expected_capabilities = protocol.make_client_capabilities()
- assert_eq(params.capabilities, expected_capabilities)
- return {
- capabilities = {
- textDocumentSync = {
- openClose = true,
- change = protocol.TextDocumentSyncKind.Incremental,
- willSave = true,
- willSaveWaitUntil = true,
- save = {
- includeText = true,
- },
- },
- },
- }
- end,
- body = function()
- notify('start')
- expect_notification('textDocument/didOpen', {
- textDocument = {
- languageId = '',
- text = table.concat({ 'testing', '123' }, '\n') .. '\n',
- uri = 'file://',
- version = 0,
- },
- })
- expect_notification('textDocument/didChange', {
- textDocument = {
- uri = 'file://',
- version = 3,
- },
- contentChanges = {
- {
- range = {
- start = { line = 1, character = 3 },
- ['end'] = { line = 1, character = 3 },
- },
- rangeLength = 0,
- text = 'boop',
- },
- },
- })
- expect_notification('finish')
- notify('finish')
- end,
- }
- end
- function tests.basic_check_buffer_open_and_change_incremental_editing()
- skeleton {
- on_init = function(params)
- local expected_capabilities = protocol.make_client_capabilities()
- assert_eq(params.capabilities, expected_capabilities)
- return {
- capabilities = {
- textDocumentSync = protocol.TextDocumentSyncKind.Incremental,
- },
- }
- end,
- body = function()
- notify('start')
- expect_notification('textDocument/didOpen', {
- textDocument = {
- languageId = '',
- text = table.concat({ 'testing', '123' }, '\n'),
- uri = 'file://',
- version = 0,
- },
- })
- expect_notification('textDocument/didChange', {
- textDocument = {
- uri = 'file://',
- version = 3,
- },
- contentChanges = {
- {
- range = {
- start = { line = 0, character = 0 },
- ['end'] = { line = 1, character = 0 },
- },
- rangeLength = 4,
- text = 'testing\n\n',
- },
- },
- })
- expect_notification('finish')
- notify('finish')
- end,
- }
- end
- function tests.invalid_header()
- io.stdout:write('Content-length: \r\n')
- end
- function tests.decode_nil()
- skeleton {
- on_init = function(_)
- return { capabilities = {} }
- end,
- body = function()
- notify('start')
- notify('workspace/executeCommand', {
- arguments = { 'EXTRACT_METHOD', { metadata = { field = vim.NIL } }, 3, 0, 6123, vim.NIL },
- command = 'refactor.perform',
- title = 'EXTRACT_METHOD',
- })
- notify('finish')
- end,
- }
- end
- function tests.code_action_with_resolve()
- skeleton {
- on_init = function()
- return {
- capabilities = {
- codeActionProvider = {
- resolveProvider = true,
- },
- },
- }
- end,
- body = function()
- notify('start')
- local cmd = {
- title = 'Command 1',
- command = 'dummy1',
- }
- expect_request('textDocument/codeAction', function()
- return nil, { cmd }
- end)
- expect_request('codeAction/resolve', function()
- return nil, cmd
- end)
- notify('shutdown')
- end,
- }
- end
- function tests.code_action_server_side_command()
- skeleton({
- on_init = function()
- return {
- capabilities = {
- codeActionProvider = {
- resolveProvider = false,
- },
- executeCommandProvider = {
- commands = { 'dummy1' },
- },
- },
- }
- end,
- body = function()
- notify('start')
- local cmd = {
- title = 'Command 1',
- command = 'dummy1',
- }
- expect_request('textDocument/codeAction', function()
- return nil, { cmd }
- end)
- expect_request('workspace/executeCommand', function()
- return nil, cmd
- end)
- notify('shutdown')
- end,
- })
- end
- function tests.code_action_filter()
- skeleton {
- on_init = function()
- return {
- capabilities = {
- codeActionProvider = {
- resolveProvider = false,
- },
- },
- }
- end,
- body = function()
- notify('start')
- local action = {
- title = 'Action 1',
- command = 'command',
- }
- local preferred_action = {
- title = 'Action 2',
- isPreferred = true,
- command = 'preferred_command',
- }
- local type_annotate_action = {
- title = 'Action 3',
- kind = 'type-annotate',
- command = 'type_annotate_command',
- }
- local type_annotate_foo_action = {
- title = 'Action 4',
- kind = 'type-annotate.foo',
- command = 'type_annotate_foo_command',
- }
- expect_request('textDocument/codeAction', function()
- return nil, { action, preferred_action, type_annotate_action, type_annotate_foo_action }
- end)
- expect_request('textDocument/codeAction', function()
- return nil, { action, preferred_action, type_annotate_action, type_annotate_foo_action }
- end)
- notify('shutdown')
- end,
- }
- end
- function tests.clientside_commands()
- skeleton {
- on_init = function()
- return {
- capabilities = {},
- }
- end,
- body = function()
- notify('start')
- notify('shutdown')
- end,
- }
- end
- function tests.codelens_refresh_lock()
- skeleton {
- on_init = function()
- return {
- capabilities = {
- codeLensProvider = { resolveProvider = true },
- },
- }
- end,
- body = function()
- notify('start')
- expect_request('textDocument/codeLens', function()
- return { code = -32002, message = 'ServerNotInitialized' }, nil
- end)
- expect_request('textDocument/codeLens', function()
- local lenses = {
- {
- range = {
- start = { line = 0, character = 0 },
- ['end'] = { line = 0, character = 3 },
- },
- command = { title = 'Lens1', command = 'Dummy' },
- },
- }
- return nil, lenses
- end)
- expect_request('textDocument/codeLens', function()
- local lenses = {
- {
- range = {
- start = { line = 0, character = 0 },
- ['end'] = { line = 0, character = 3 },
- },
- command = { title = 'Lens2', command = 'Dummy' },
- },
- }
- return nil, lenses
- end)
- notify('shutdown')
- end,
- }
- end
- function tests.basic_formatting()
- skeleton {
- on_init = function()
- return {
- capabilities = {
- documentFormattingProvider = true,
- },
- }
- end,
- body = function()
- notify('start')
- expect_request('textDocument/formatting', function()
- return nil, {}
- end)
- notify('shutdown')
- end,
- }
- end
- function tests.range_formatting()
- skeleton {
- on_init = function()
- return {
- capabilities = {
- documentFormattingProvider = true,
- documentRangeFormattingProvider = true,
- },
- }
- end,
- body = function()
- notify('start')
- expect_request('textDocument/rangeFormatting', function()
- return nil, {}
- end)
- notify('shutdown')
- end,
- }
- end
- function tests.ranges_formatting()
- skeleton {
- on_init = function()
- return {
- capabilities = {
- documentFormattingProvider = true,
- documentRangeFormattingProvider = {
- rangesSupport = true,
- },
- },
- }
- end,
- body = function()
- notify('start')
- expect_request('textDocument/rangesFormatting', function()
- return nil, {}
- end)
- notify('shutdown')
- end,
- }
- end
- function tests.set_defaults_all_capabilities()
- skeleton {
- on_init = function(_)
- return {
- capabilities = {
- definitionProvider = true,
- completionProvider = true,
- documentRangeFormattingProvider = true,
- hoverProvider = true,
- },
- }
- end,
- body = function()
- notify('test')
- end,
- }
- end
- function tests.inlay_hint()
- skeleton {
- on_init = function(params)
- local expected_capabilities = protocol.make_client_capabilities()
- assert_eq(params.capabilities, expected_capabilities)
- return {
- capabilities = {
- inlayHintProvider = true,
- },
- }
- end,
- body = function()
- notify('start')
- expect_request('textDocument/inlayHint', function()
- return nil, {}
- end)
- expect_notification('finish')
- notify('finish')
- end,
- }
- end
- -- Tests will be indexed by test_name
- local test_name = arg[1]
- local timeout = arg[2]
- assert(type(test_name) == 'string', 'test_name must be specified as first arg.')
- local kill_timer = assert(vim.uv.new_timer())
- kill_timer:start(timeout or 1e3, 0, function()
- kill_timer:stop()
- kill_timer:close()
- log('ERROR', 'LSP', 'TIMEOUT')
- io.stderr:write('TIMEOUT')
- os.exit(100)
- end)
- local status, err = pcall(assert(tests[test_name], 'Test not found'))
- kill_timer:stop()
- kill_timer:close()
- if not status then
- log('ERROR', 'LSP', tostring(err))
- io.stderr:write(err)
- vim.cmd [[101cquit]]
- end
|