]> git.madduck.net Git - etc/vim.git/blob - test/completion/test_lsp_completion_messages.vader

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 / completion / test_lsp_completion_messages.vader
1 Before:
2   Save g:ale_completion_delay
3   Save g:ale_completion_enabled
4   Save g:ale_completion_max_suggestions
5   Save g:ale_completion_info
6   Save g:ale_completion_autoimport
7   Save &l:omnifunc
8   Save &l:completeopt
9
10   let g:ale_completion_enabled = v:true
11   let g:ale_completion_autoimport = v:true
12
13   call ale#test#SetDirectory('/testplugin/test/completion')
14   call ale#test#SetFilename('dummy.txt')
15
16   runtime autoload/ale/lsp.vim
17
18   let g:message_list = []
19   let g:capability_checked = ''
20   let g:conn_id = v:null
21   let g:Callback = ''
22   let g:init_callback_list = []
23
24   function! ale#lsp_linter#StartLSP(buffer, linter, Callback) abort
25     let g:conn_id = ale#lsp#Register('executable', '/foo/bar', '', {})
26     call ale#lsp#MarkDocumentAsOpen(g:conn_id, a:buffer)
27
28     let l:details = {
29     \ 'command': 'foobar',
30     \ 'buffer': a:buffer,
31     \ 'connection_id': g:conn_id,
32     \ 'project_root': '/foo/bar',
33     \}
34
35     call add(g:init_callback_list, {-> a:Callback(a:linter, l:details)})
36   endfunction
37
38   " Pretend we're in insert mode for most tests.
39   function! ale#util#Mode(...) abort
40     return 'i'
41   endfunction
42
43   function! ale#lsp#HasCapability(conn_id, capability) abort
44     let g:capability_checked = a:capability
45
46     return 1
47   endfunction
48
49   function! ale#lsp#RegisterCallback(conn_id, callback) abort
50     let g:Callback = a:callback
51   endfunction
52
53   " Replace the Send function for LSP, so we can monitor calls to it.
54   function! ale#lsp#Send(conn_id, message) abort
55     call add(g:message_list, a:message)
56
57     return 1
58   endfunction
59
60 After:
61   Restore
62
63   if g:conn_id isnot v:null
64     call ale#lsp#RemoveConnectionWithID(g:conn_id)
65   endif
66
67   unlet! g:message_list
68   unlet! g:capability_checked
69   unlet! g:init_callback_list
70   unlet! g:conn_id
71   unlet! g:Callback
72   unlet! b:ale_old_omnifunc
73   unlet! b:ale_old_completeopt
74   unlet! b:ale_completion_info
75   unlet! b:ale_complete_done_time
76   unlet! b:ale_linters
77   unlet! b:ale_tsserver_completion_names
78
79   " Reset the function.
80   function! ale#util#Mode(...) abort
81     return call('mode', a:000)
82   endfunction
83
84   call ale#test#RestoreDirectory()
85   call ale#linter#Reset()
86
87   " Stop any timers we left behind.
88   " This stops the tests from failing randomly.
89   call ale#completion#StopTimer()
90
91   runtime autoload/ale/completion.vim
92   runtime autoload/ale/lsp.vim
93   runtime autoload/ale/lsp_linter.vim
94
95 Given typescript(Some typescript file):
96   foo
97   somelongerline
98   bazxyzxyzxyz
99
100 Execute(The right message should be sent for the initial tsserver request):
101   runtime ale_linters/typescript/tsserver.vim
102   let b:ale_linters = ['tsserver']
103   " The cursor position needs to match what was saved before.
104   call setpos('.', [bufnr(''), 1, 3, 0])
105
106   call ale#completion#GetCompletions('ale-automatic')
107
108   " We shouldn't register the callback yet.
109   AssertEqual '''''', string(g:Callback)
110
111   AssertEqual 1, len(g:init_callback_list)
112   call map(g:init_callback_list, 'v:val()')
113
114   AssertEqual 'completion', g:capability_checked
115
116   " We should send the right callback.
117   AssertEqual
118   \ 'function(''ale#completion#HandleTSServerResponse'')',
119   \ string(g:Callback)
120   " We should send the right message.
121   AssertEqual
122   \ [[0, 'ts@completions', {
123   \  'file': expand('%:p'),
124   \  'line': 1,
125   \  'offset': 3,
126   \  'prefix': 'fo',
127   \  'includeExternalModuleExports': g:ale_completion_autoimport,
128   \ }]],
129   \ g:message_list
130   " We should set up the completion info correctly.
131   AssertEqual
132   \ {
133   \   'line_length': 3,
134   \   'conn_id': g:conn_id,
135   \   'column': 3,
136   \   'request_id': 1,
137   \   'line': 1,
138   \   'prefix': 'fo',
139   \   'source': 'ale-automatic',
140   \ },
141   \ get(b:, 'ale_completion_info', {})
142
143 Execute(The right message sent to the tsserver LSP when the first completion message is received):
144   " The cursor position needs to match what was saved before.
145   call setpos('.', [bufnr(''), 1, 1, 0])
146   let b:ale_completion_info = {
147   \ 'conn_id': 123,
148   \ 'prefix': 'f',
149   \ 'request_id': 4,
150   \ 'line': 1,
151   \ 'column': 1,
152   \}
153   " We should only show up to this many suggestions.
154   let g:ale_completion_max_suggestions = 3
155
156   " Handle the response for completions.
157   call ale#completion#HandleTSServerResponse(123, {
158   \ 'request_seq': 4,
159   \ 'command': 'completions',
160   \ 'body': [
161   \   {'name': 'Baz'},
162   \   {'name': 'dingDong'},
163   \   {'name': 'Foo', 'source': '/path/to/foo.ts'},
164   \   {'name': 'FooBar'},
165   \   {'name': 'frazzle'},
166   \   {'name': 'FFS'},
167   \ ],
168   \})
169
170   " We should save the names we got in the buffer, as TSServer doesn't return
171   " details for every name.
172   AssertEqual [{
173   \  'word': 'Foo',
174   \  'source': '/path/to/foo.ts',
175   \ }, {
176   \  'word': 'FooBar',
177   \  'source': '',
178   \ }, {
179   \  'word': 'frazzle',
180   \  'source': '',
181   \}],
182   \ get(b:, 'ale_tsserver_completion_names', [])
183
184   " The entry details messages should have been sent.
185   AssertEqual
186   \ [[
187   \   0,
188   \   'ts@completionEntryDetails',
189   \   {
190   \     'file': expand('%:p'),
191   \     'entryNames': [{
192   \          'name': 'Foo',
193   \          'source': '/path/to/foo.ts',
194   \         }, {
195   \          'name': 'FooBar',
196   \         }, {
197   \          'name': 'frazzle',
198   \     }],
199   \     'offset': 1,
200   \     'line': 1,
201   \   },
202   \ ]],
203   \ g:message_list
204
205 Given python(Some Python file):
206   foo
207   somelongerline
208   bazxyzxyzxyz
209
210 Execute(The right message should be sent for the initial LSP request):
211   runtime ale_linters/python/pylsp.vim
212   let b:ale_linters = ['pylsp']
213   " The cursor position needs to match what was saved before.
214   call setpos('.', [bufnr(''), 1, 5, 0])
215
216   call ale#completion#GetCompletions('ale-automatic')
217
218   " We shouldn't register the callback yet.
219   AssertEqual '''''', string(g:Callback)
220
221   AssertEqual 1, len(g:init_callback_list)
222   call map(g:init_callback_list, 'v:val()')
223
224   AssertEqual 'completion', g:capability_checked
225
226   " We should send the right callback.
227   AssertEqual
228   \ 'function(''ale#completion#HandleLSPResponse'')',
229   \ string(g:Callback)
230   " We should send the right message.
231   " The character index needs to be at most the index of the last character on
232   " the line, or integration with pylsp will be broken.
233   "
234   " We need to send the message for changing the document first.
235   AssertEqual
236   \ [
237   \   [1, 'textDocument/didChange', {
238   \     'textDocument': {
239   \         'uri': ale#path#ToFileURI(expand('%:p')),
240   \         'version': g:ale_lsp_next_version_id - 1,
241   \     },
242   \     'contentChanges': [{'text': join(getline(1, '$'), "\n") . "\n"}]
243   \   }],
244   \   [0, 'textDocument/completion', {
245   \   'textDocument': {'uri': ale#path#ToFileURI(expand('%:p'))},
246   \   'position': {'line': 0, 'character': 2},
247   \   }],
248   \ ],
249   \ g:message_list
250   " We should set up the completion info correctly.
251   AssertEqual
252   \ {
253   \   'line_length': 3,
254   \   'conn_id': g:conn_id,
255   \   'column': 3,
256   \   'request_id': 1,
257   \   'line': 1,
258   \   'prefix': 'fo',
259   \   'source': 'ale-automatic',
260   \   'completion_filter': 'ale#completion#python#CompletionItemFilter',
261   \ },
262   \ get(b:, 'ale_completion_info', {})
263
264 Execute(Two completion requests shouldn't be sent in a row):
265   call ale#linter#PreventLoading('python')
266   call ale#linter#Define('python', {
267   \   'name': 'foo',
268   \   'lsp': 'stdio',
269   \   'executable': 'foo',
270   \   'command': 'foo',
271   \   'project_root': {-> '/foo/bar'},
272   \})
273   call ale#linter#Define('python', {
274   \   'name': 'bar',
275   \   'lsp': 'stdio',
276   \   'executable': 'foo',
277   \   'command': 'foo',
278   \   'project_root': {-> '/foo/bar'},
279   \})
280   let b:ale_linters = ['foo', 'bar']
281
282   " The cursor position needs to match what was saved before.
283   call setpos('.', [bufnr(''), 1, 5, 0])
284
285   call ale#completion#GetCompletions('ale-automatic')
286
287   " We shouldn't register the callback yet.
288   AssertEqual '''''', string(g:Callback)
289
290   AssertEqual 2, len(g:init_callback_list)
291   call map(g:init_callback_list, 'v:val()')
292
293   AssertEqual 'completion', g:capability_checked
294
295   " We should only send one completion message for two LSP servers.
296   AssertEqual
297   \ [
298   \   [1, 'textDocument/didChange', {
299   \     'textDocument': {
300   \         'uri': ale#path#ToFileURI(expand('%:p')),
301   \         'version': g:ale_lsp_next_version_id - 1,
302   \     },
303   \     'contentChanges': [{'text': join(getline(1, '$'), "\n") . "\n"}]
304   \   }],
305   \   [0, 'textDocument/completion', {
306   \   'textDocument': {'uri': ale#path#ToFileURI(expand('%:p'))},
307   \   'position': {'line': 0, 'character': 2},
308   \   }],
309   \ ],
310   \ g:message_list