]> git.madduck.net Git - etc/vim.git/blob - test/lua/ale_lsp_spec.lua

madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

All patches and comments are welcome. Please squash your changes to logical commits before using git-format-patch and git-send-email to patches@git.madduck.net. If you'd read over the Git project's submission guidelines and adhered to them, I'd be especially grateful.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

Squashed '.vim/bundle/ale/' content from commit 22185c4c
[etc/vim.git] / test / lua / ale_lsp_spec.lua
1 local eq = assert.are.same
2 local lsp = require("ale.lsp")
3
4 describe("ale.lsp.start", function()
5     local start_calls
6     local rpc_connect_calls
7     local vim_fn_calls
8     local defer_calls
9     local nvim_default_capabilities
10
11     setup(function()
12         _G.vim = {
13             defer_fn = function(func, delay)
14                 table.insert(defer_calls, {func, delay})
15             end,
16             fn = setmetatable({}, {
17                 __index = function(_, key)
18                     return function(...)
19                         table.insert(vim_fn_calls, {key, ...})
20
21                         if key == "ale#lsp#GetLanguage" then
22                             return "python"
23                         end
24
25                         if key ~= "ale#lsp_linter#HandleLSPDiagnostics"
26                         and key ~= "ale#lsp#UpdateCapabilities"
27                         and key ~= "ale#lsp#CallInitCallbacks"
28                         then
29                             assert(false, "Invalid ALE function: " .. key)
30                         end
31
32                         return nil
33                     end
34                 end,
35             }),
36             lsp = {
37                 rpc = {
38                     connect = function(host, port)
39                         return function(dispatch)
40                             table.insert(rpc_connect_calls, {
41                                 host = host,
42                                 port = port,
43                                 dispatch = dispatch,
44                             })
45                         end
46                     end,
47                 },
48                 start = function(...)
49                     table.insert(start_calls, {...})
50
51                     return 42
52                 end,
53                 protocol = {
54                     make_client_capabilities = function()
55                         return nvim_default_capabilities
56                     end,
57                 },
58             },
59         }
60     end)
61
62     teardown(function()
63         _G.vim = nil
64     end)
65
66     before_each(function()
67         start_calls = {}
68         rpc_connect_calls = {}
69         vim_fn_calls = {}
70         defer_calls = {}
71         nvim_default_capabilities = {
72             textDocument = {},
73         }
74     end)
75
76     it("should start lsp programs with the correct arguments", function()
77         lsp.start({
78             name = "server:/code",
79             cmd = "server",
80             root_dir = "/code",
81             -- This Boolean value somehow ends up in Dictionaries from
82             -- Vim for init_options, and we need to remove it.
83             init_options = {[true] = 123},
84         })
85
86         -- Remove arguments with functions we can't apply equality checks
87         -- for easily.
88         for _, args in pairs(start_calls) do
89             args[1].handlers = nil
90             args[1].on_init = nil
91             args[1].get_language_id = nil
92         end
93
94         eq({
95             {
96                 {
97                     cmd = "server",
98                     name = "server:/code",
99                     root_dir = "/code",
100                     init_options = {},
101                 },
102                 {attach = false, silent = true}
103             }
104         }, start_calls)
105         eq({}, vim_fn_calls)
106     end)
107
108     it("should start lsp socket connections with the correct arguments", function()
109         lsp.start({
110             name = "localhost:1234:/code",
111             host = "localhost",
112             port = 1234,
113             root_dir = "/code",
114             init_options = {foo = "bar"},
115         })
116
117         local cmd
118
119         -- Remove arguments with functions we can't apply equality checks
120         -- for easily.
121         for _, args in pairs(start_calls) do
122             cmd = args[1].cmd
123             args[1].cmd = nil
124             args[1].handlers = nil
125             args[1].on_init = nil
126             args[1].get_language_id = nil
127         end
128
129         eq({
130             {
131                 {
132                     name = "localhost:1234:/code",
133                     root_dir = "/code",
134                     init_options = {foo = "bar"},
135                 },
136                 {attach = false, silent = true}
137             }
138         }, start_calls)
139
140         cmd("dispatch_value")
141
142         eq({
143             {dispatch = "dispatch_value", host = "localhost", port = 1234},
144         }, rpc_connect_calls)
145         eq({}, vim_fn_calls)
146     end)
147
148     it("should return the client_id value from vim.lsp.start", function()
149         eq(42, lsp.start({}))
150     end)
151
152     it("should implement get_language_id correctly", function()
153         lsp.start({name = "server:/code"})
154
155         eq(1, #start_calls)
156         eq("python", start_calls[1][1].get_language_id(347, "ftype"))
157         eq({{"ale#lsp#GetLanguage", "server:/code", 347}}, vim_fn_calls)
158     end)
159
160     it("should enable dynamicRegistration for the pull model", function()
161         nvim_default_capabilities = {textDocument = {diagnostic = {}}}
162
163         lsp.start({name = "server:/code"})
164         eq(1, #start_calls)
165
166         eq(
167             {
168                 textDocument = {
169                     diagnostic = {
170                         dynamicRegistration = true,
171                     },
172                 },
173             },
174             start_calls[1][1].capabilities
175         )
176     end)
177
178     it("should initialize clients with ALE correctly", function()
179         lsp.start({name = "server:/code"})
180
181         eq(1, #start_calls)
182
183         start_calls[1][1].on_init({server_capabilities = {cap = 1}})
184
185         eq({
186             {"ale#lsp#UpdateCapabilities", "server:/code", {cap = 1}},
187         }, vim_fn_calls)
188         eq(1, #defer_calls)
189         eq(2, #defer_calls[1])
190         eq("function", type(defer_calls[1][1]))
191         eq(0, defer_calls[1][2])
192
193         defer_calls[1][1]()
194
195         eq({
196             {"ale#lsp#UpdateCapabilities", "server:/code", {cap = 1}},
197             {"ale#lsp#CallInitCallbacks", "server:/code"},
198         }, vim_fn_calls)
199     end)
200
201     it("should configure handlers correctly", function()
202         lsp.start({name = "server:/code"})
203
204         eq(1, #start_calls)
205
206         local handlers = start_calls[1][1].handlers
207         local handler_names = {}
208
209         -- get keys from handlers
210         for key, _ in pairs(handlers) do
211             -- add key to handler_names mapping
212             handler_names[key] = true
213         end
214
215         eq({
216             ["textDocument/publishDiagnostics"] = true,
217             ["textDocument/diagnostic"] = true,
218             ["workspace/diagnostic/refresh"] = true,
219         }, handler_names)
220     end)
221
222     it("should handle push model published diagnostics", function()
223         lsp.start({name = "server:/code"})
224
225         eq(1, #start_calls)
226
227         local handlers = start_calls[1][1].handlers
228
229         eq("function", type(handlers["textDocument/publishDiagnostics"]))
230
231         handlers["textDocument/publishDiagnostics"](nil, {
232             uri = "file://code/foo.py",
233             diagnostics = {
234                 {
235                     lnum = 1,
236                     end_lnum = 2,
237                     col = 3,
238                     end_col = 5,
239                     severity = 1,
240                     code = "123",
241                     message = "Warning message",
242                 }
243             },
244         })
245
246         eq({
247             {
248                 "ale#lsp_linter#HandleLSPDiagnostics",
249                 "server:/code",
250                 "file://code/foo.py",
251                 {
252                     {
253                         lnum = 1,
254                         end_lnum = 2,
255                         col = 3,
256                         end_col = 5,
257                         severity = 1,
258                         code = "123",
259                         message = "Warning message",
260                     },
261                 },
262             },
263         }, vim_fn_calls)
264     end)
265
266     it("should respond to workspace diagnostic refresh requests", function()
267         lsp.start({name = "server:/code"})
268
269         eq(1, #start_calls)
270
271         local handlers = start_calls[1][1].handlers
272
273         eq("function", type(handlers["workspace/diagnostic/refresh"]))
274
275         eq({}, handlers["workspace/diagnostic/refresh"]())
276     end)
277
278     it("should handle pull model diagnostics", function()
279         lsp.start({name = "server:/code"})
280
281         eq(1, #start_calls)
282
283         local handlers = start_calls[1][1].handlers
284
285         eq("function", type(handlers["textDocument/diagnostic"]))
286
287         handlers["textDocument/diagnostic"](
288             nil,
289             {
290                 kind = "full",
291                 items = {
292                     {
293                         lnum = 1,
294                         end_lnum = 2,
295                         col = 3,
296                         end_col = 5,
297                         severity = 1,
298                         code = "123",
299                         message = "Warning message",
300                     }
301                 },
302             },
303             {
304                 params = {
305                     textDocument = {
306                         uri = "file://code/foo.py",
307                     },
308                 },
309             }
310         )
311
312         eq({
313             {
314                 "ale#lsp_linter#HandleLSPDiagnostics",
315                 "server:/code",
316                 "file://code/foo.py",
317                 {
318                     {
319                         lnum = 1,
320                         end_lnum = 2,
321                         col = 3,
322                         end_col = 5,
323                         severity = 1,
324                         code = "123",
325                         message = "Warning message",
326                     },
327                 },
328             },
329         }, vim_fn_calls)
330     end)
331
332     it("should handle unchanged pull model diagnostics", function()
333         lsp.start({name = "server:/code"})
334
335         eq(1, #start_calls)
336
337         local handlers = start_calls[1][1].handlers
338
339         eq("function", type(handlers["textDocument/diagnostic"]))
340
341         handlers["textDocument/diagnostic"](
342             nil,
343             {kind = "unchanged"},
344             {
345                 params = {
346                     textDocument = {
347                         uri = "file://code/foo.py",
348                     },
349                 },
350             }
351         )
352
353         eq({
354             {
355                 "ale#lsp_linter#HandleLSPDiagnostics",
356                 "server:/code",
357                 "file://code/foo.py",
358                 "unchanged",
359             },
360         }, vim_fn_calls)
361     end)
362 end)