]> git.madduck.net Git - etc/vim.git/blob - .vim/bundle/ale/test/completion/test_lsp_completion_parsing.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:

Merge commit '56df844d3c39ec494dacc69eae34272b27db185a' as '.vim/bundle/asyncomplete'
[etc/vim.git] / .vim / bundle / ale / test / completion / test_lsp_completion_parsing.vader
1 Before:
2   Save g:ale_completion_autoimport
3   Save g:ale_completion_max_suggestions
4
5   let g:ale_completion_max_suggestions = 50
6
7 After:
8   Restore
9
10   unlet! b:ale_completion_info
11
12 Execute(Should handle Rust completion results correctly):
13   let g:ale_completion_autoimport = 0
14
15   AssertEqual
16   \ [
17   \   {'word': 'new', 'dup': 0, 'menu': 'pub fn new() -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
18   \   {'word': 'with_capacity', 'dup': 0, 'menu': 'pub fn with_capacity(capacity: usize) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
19   \   {'word': 'from_utf8', 'dup': 0, 'menu': 'pub fn from_utf8(vec: Vec<u8>) -> Result<String, FromUtf8Error>', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
20   \   {'word': 'from_utf8_lossy', 'dup': 0, 'menu': 'pub fn from_utf8_lossy<''a>(v: &''a [u8]) -> Cow<''a, str>', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
21   \   {'word': 'from_utf16', 'dup': 0, 'menu': 'pub fn from_utf16(v: &[u16]) -> Result<String, FromUtf16Error>', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
22   \   {'word': 'from_utf16_lossy', 'dup': 0, 'menu': 'pub fn from_utf16_lossy(v: &[u16]) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
23   \   {'word': 'from_raw_parts', 'dup': 0, 'menu': 'pub unsafe fn from_raw_parts(buf: *mut u8, length: usize, capacity: usize) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
24   \   {'word': 'from_utf8_unchecked', 'dup': 0, 'menu': 'pub unsafe fn from_utf8_unchecked(bytes: Vec<u8>) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
25   \   {'word': 'from_iter', 'dup': 0, 'menu': 'fn from_iter<I: IntoIterator<Item = char>>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
26   \   {'word': 'from_iter', 'dup': 0, 'menu': 'fn from_iter<I: IntoIterator<Item = &''a char>>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
27   \   {'word': 'from_iter', 'dup': 0, 'menu': 'fn from_iter<I: IntoIterator<Item = &''a str>>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
28   \   {'word': 'from_iter', 'dup': 0, 'menu': 'fn from_iter<I: IntoIterator<Item = String>>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
29   \   {'word': 'from_iter', 'dup': 0, 'menu': 'fn from_iter<I: IntoIterator<Item = Cow<''a, str>>>(iter: I) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
30   \   {'word': 'Searcher', 'dup': 0, 'menu': 'type Searcher = <&''b str as Pattern<''a>>::Searcher;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
31   \   {'word': 'default', 'dup': 0, 'menu': 'fn default() -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
32   \   {'word': 'Output', 'dup': 0, 'menu': 'type Output = String;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
33   \   {'word': 'Output', 'dup': 0, 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
34   \   {'word': 'Output', 'dup': 0, 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
35   \   {'word': 'Output', 'dup': 0, 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
36   \   {'word': 'Output', 'dup': 0, 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
37   \   {'word': 'Output', 'dup': 0, 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
38   \   {'word': 'Output', 'dup': 0, 'menu': 'type Output = str;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
39   \   {'word': 'Target', 'dup': 0, 'menu': 'type Target = str;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
40   \   {'word': 'Err', 'dup': 0, 'menu': 'type Err = ParseError;', 'info': '', 'kind': 't', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
41   \   {'word': 'from_str', 'dup': 0, 'menu': 'fn from_str(s: &str) -> Result<String, ParseError>', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
42   \   {'word': 'from', 'dup': 0, 'menu': 'fn from(s: &''a str) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
43   \   {'word': 'from', 'dup': 0, 'menu': 'fn from(s: Box<str>) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
44   \   {'word': 'from', 'dup': 0, 'menu': 'fn from(s: Cow<''a, str>) -> String', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
45   \   {'word': 'to_vec', 'dup': 0, 'menu': 'pub fn to_vec(&self) -> Vec<T> where T: Clone,', 'info': '', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
46   \],
47   \ ale#completion#ParseLSPCompletions({
48   \   "jsonrpc":"2.0",
49   \   "id":65,
50   \   "result":[
51   \     {
52   \       "label":"new",
53   \       "kind":3,
54   \       "detail":"pub fn new() -> String"
55   \     },
56   \     {
57   \       "label":"with_capacity",
58   \       "kind":3,
59   \       "detail":"pub fn with_capacity(capacity: usize) -> String"
60   \     },
61   \     {
62   \       "label":"from_utf8",
63   \       "kind":3,
64   \       "detail":"pub fn from_utf8(vec: Vec<u8>) -> Result<String, FromUtf8Error>"
65   \     },
66   \     {
67   \       "label":"from_utf8_lossy",
68   \       "kind":3,
69   \       "detail":"pub fn from_utf8_lossy<'a>(v: &'a [u8]) -> Cow<'a, str>"
70   \     },
71   \     {
72   \       "label":"from_utf16",
73   \       "kind":3,
74   \       "detail":"pub fn from_utf16(v: &[u16]) -> Result<String, FromUtf16Error>"
75   \     },
76   \     {
77   \       "label":"from_utf16_lossy",
78   \       "kind":3,
79   \       "detail":"pub fn from_utf16_lossy(v: &[u16]) -> String"
80   \     },
81   \     {
82   \       "label":"from_raw_parts",
83   \       "kind":3,
84   \       "detail":"pub unsafe fn from_raw_parts(buf: *mut u8, length: usize, capacity: usize) -> String"
85   \     },
86   \     {
87   \       "label":"from_utf8_unchecked",
88   \       "kind":3,
89   \       "detail":"pub unsafe fn from_utf8_unchecked(bytes: Vec<u8>) -> String"
90   \     },
91   \     {
92   \       "label":"from_iter",
93   \       "kind":3,
94   \       "detail":"fn from_iter<I: IntoIterator<Item = char>>(iter: I) -> String"
95   \     },
96   \     {
97   \       "label":"from_iter",
98   \       "kind":3,
99   \       "detail":"fn from_iter<I: IntoIterator<Item = &'a char>>(iter: I) -> String"
100   \     },
101   \     {
102   \       "label":"from_iter",
103   \       "kind":3,
104   \       "detail":"fn from_iter<I: IntoIterator<Item = &'a str>>(iter: I) -> String"
105   \     },
106   \     {
107   \       "label":"from_iter",
108   \       "kind":3,
109   \       "detail":"fn from_iter<I: IntoIterator<Item = String>>(iter: I) -> String"
110   \     },
111   \     {
112   \       "label":"from_iter",
113   \       "kind":3,
114   \       "detail":"fn from_iter<I: IntoIterator<Item = Cow<'a, str>>>(iter: I) -> String"
115   \     },
116   \     {
117   \       "label":"Searcher",
118   \       "kind":8,
119   \       "detail":"type Searcher = <&'b str as Pattern<'a>>::Searcher;"
120   \     },
121   \     {
122   \       "label":"default",
123   \       "kind":3,
124   \       "detail":"fn default() -> String"
125   \     },
126   \     {
127   \       "label":"Output",
128   \       "kind":8,
129   \       "detail":"type Output = String;"
130   \     },
131   \     {
132   \       "label":"Output",
133   \       "kind":8,
134   \       "detail":"type Output = str;"
135   \     },
136   \     {
137   \       "label":"Output",
138   \       "kind":8,
139   \       "detail":"type Output = str;"
140   \     },
141   \     {
142   \       "label":"Output",
143   \       "kind":8,
144   \       "detail":"type Output = str;"
145   \     },
146   \     {
147   \       "label":"Output",
148   \       "kind":8,
149   \       "detail":"type Output = str;"
150   \     },
151   \     {
152   \       "label":"Output",
153   \       "kind":8,
154   \       "detail":"type Output = str;"
155   \     },
156   \     {
157   \       "label":"Output",
158   \       "kind":8,
159   \       "detail":"type Output = str;"
160   \     },
161   \     {
162   \       "label":"Target",
163   \       "kind":8,
164   \       "detail":"type Target = str;"
165   \     },
166   \     {
167   \       "label":"Err",
168   \       "kind":8,
169   \       "detail":"type Err = ParseError;"
170   \     },
171   \     {
172   \       "label":"from_str",
173   \       "kind":3,
174   \       "detail":"fn from_str(s: &str) -> Result<String, ParseError>"
175   \     },
176   \     {
177   \       "label":"from",
178   \       "kind":3,
179   \       "detail":"fn from(s: &'a str) -> String"
180   \     },
181   \     {
182   \       "label":"from",
183   \       "kind":3,
184   \       "detail":"fn from(s: Box<str>) -> String"
185   \     },
186   \     {
187   \       "label":"from",
188   \       "kind":3,
189   \       "detail":"fn from(s: Cow<'a, str>) -> String"
190   \     },
191   \     {
192   \       "label":"to_vec",
193   \       "kind":3,
194   \       "detail":"pub fn to_vec(&self) -> Vec<T>\nwhere\n        T: Clone,"
195   \     }
196   \   ]
197   \ })
198
199 Execute(Should handle Python completion results correctly):
200   let g:ale_completion_autoimport = 0
201   let b:ale_completion_info = {
202   \ 'completion_filter': 'ale#completion#python#CompletionItemFilter',
203   \}
204
205   AssertEqual
206   \ [
207   \   {'word': 'what', 'dup': 0, 'menu': 'example-python-project.bar.Bar', 'info': "what()\n\n", 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
208   \ ],
209   \ ale#completion#ParseLSPCompletions({
210   \    "jsonrpc":"2.0",
211   \    "id":6,
212   \    "result":{
213   \       "isIncomplete":v:false,
214   \       "items":[
215   \          {
216   \             "label":"what()",
217   \             "kind":3,
218   \             "detail":"example-python-project.bar.Bar",
219   \             "documentation":"what()\n\n",
220   \             "sortText":"awhat",
221   \             "insertText":"what"
222   \          },
223   \          {
224   \             "label":"__class__",
225   \             "kind":7,
226   \             "detail":"object",
227   \             "documentation":"type(object_or_name, bases, dict)\ntype(object) -> the object's type\ntype(name, bases, dict) -> a new type",
228   \             "sortText":"z__class__",
229   \             "insertText":"__class__"
230   \          },
231   \          {
232   \             "label":"__delattr__(name)",
233   \             "kind":3,
234   \             "detail":"object",
235   \             "documentation":"Implement delattr(self, name).",
236   \             "sortText":"z__delattr__",
237   \             "insertText":"__delattr__"
238   \          },
239   \          {
240   \             "label":"__dir__()",
241   \             "kind":3,
242   \             "detail":"object",
243   \             "documentation":"__dir__() -> list\ndefault dir() implementation",
244   \             "sortText":"z__dir__",
245   \             "insertText":"__dir__"
246   \          },
247   \          {
248   \             "label":"__doc__",
249   \             "kind":18,
250   \             "detail":"object",
251   \             "documentation":"str(object='') -> str\nstr(bytes_or_buffer[, encoding[, errors]]) -> str\n\nCreate a new string object from the given object. If encoding or\nerrors is specified, then the object must expose a data buffer\nthat will be decoded using the given encoding and error handler.\nOtherwise, returns the result of object.__str__() (if defined)\nor repr(object).\nencoding defaults to sys.getdefaultencoding().\nerrors defaults to 'strict'.",
252   \             "sortText":"z__doc__",
253   \             "insertText":"__doc__"
254   \          },
255   \          {
256   \             "label":"__eq__(value)",
257   \             "kind":3,
258   \             "detail":"object",
259   \             "documentation":"Return self==value.",
260   \             "sortText":"z__eq__",
261   \             "insertText":"__eq__"
262   \          },
263   \          {
264   \             "label":"__format__()",
265   \             "kind":3,
266   \             "detail":"object",
267   \             "documentation":"default object formatter",
268   \             "sortText":"z__format__",
269   \             "insertText":"__format__"
270   \          },
271   \          {
272   \             "label":"__ge__(value)",
273   \             "kind":3,
274   \             "detail":"object",
275   \             "documentation":"Return self>=value.",
276   \             "sortText":"z__ge__",
277   \             "insertText":"__ge__"
278   \          },
279   \          {
280   \             "label":"__getattribute__(name)",
281   \             "kind":3,
282   \             "detail":"object",
283   \             "documentation":"Return getattr(self, name).",
284   \             "sortText":"z__getattribute__",
285   \             "insertText":"__getattribute__"
286   \          },
287   \          {
288   \             "label":"__gt__(value)",
289   \             "kind":3,
290   \             "detail":"object",
291   \             "documentation":"Return self>value.",
292   \             "sortText":"z__gt__",
293   \             "insertText":"__gt__"
294   \          },
295   \          {
296   \             "label":"__hash__()",
297   \             "kind":3,
298   \             "detail":"object",
299   \             "documentation":"Return hash(self).",
300   \             "sortText":"z__hash__",
301   \             "insertText":"__hash__"
302   \          },
303   \          {
304   \             "label":"__init__(args, kwargs)",
305   \             "kind":3,
306   \             "detail":"object",
307   \             "documentation":"Initialize self.\u00a0\u00a0See help(type(self)) for accurate signature.",
308   \             "sortText":"z__init__",
309   \             "insertText":"__init__"
310   \          },
311   \          {
312   \             "label":"__init_subclass__()",
313   \             "kind":3,
314   \             "detail":"object",
315   \             "documentation":"This method is called when a class is subclassed.\n\nThe default implementation does nothing. It may be\noverridden to extend subclasses.",
316   \             "sortText":"z__init_subclass__",
317   \             "insertText":"__init_subclass__"
318   \          },
319   \          {
320   \             "label":"__le__(value)",
321   \             "kind":3,
322   \             "detail":"object",
323   \             "documentation":"Return self<=value.",
324   \             "sortText":"z__le__",
325   \             "insertText":"__le__"
326   \          },
327   \          {
328   \             "label":"__lt__(value)",
329   \             "kind":3,
330   \             "detail":"object",
331   \             "documentation":"Return self<value.",
332   \             "sortText":"z__lt__",
333   \             "insertText":"__lt__"
334   \          },
335   \          {
336   \             "label":"__ne__(value)",
337   \             "kind":3,
338   \             "detail":"object",
339   \             "documentation":"Return self!=value.",
340   \             "sortText":"z__ne__",
341   \             "insertText":"__ne__"
342   \          },
343   \          {
344   \             "label":"__new__(kwargs)",
345   \             "kind":3,
346   \             "detail":"object",
347   \             "documentation":"Create and return a new object.\u00a0\u00a0See help(type) for accurate signature.",
348   \             "sortText":"z__new__",
349   \             "insertText":"__new__"
350   \          },
351   \          {
352   \             "label":"__reduce__()",
353   \             "kind":3,
354   \             "detail":"object",
355   \             "documentation":"helper for pickle",
356   \             "sortText":"z__reduce__",
357   \             "insertText":"__reduce__"
358   \          },
359   \          {
360   \             "label":"__reduce_ex__()",
361   \             "kind":3,
362   \             "detail":"object",
363   \             "documentation":"helper for pickle",
364   \             "sortText":"z__reduce_ex__",
365   \             "insertText":"__reduce_ex__"
366   \          },
367   \          {
368   \             "label":"__repr__()",
369   \             "kind":3,
370   \             "detail":"object",
371   \             "documentation":"Return repr(self).",
372   \             "sortText":"z__repr__",
373   \             "insertText":"__repr__"
374   \          },
375   \          {
376   \             "label":"__setattr__(name, value)",
377   \             "kind":3,
378   \             "detail":"object",
379   \             "documentation":"Implement setattr(self, name, value).",
380   \             "sortText":"z__setattr__",
381   \             "insertText":"__setattr__"
382   \          },
383   \          {
384   \             "label":"__sizeof__()",
385   \             "kind":3,
386   \             "detail":"object",
387   \             "documentation":"__sizeof__() -> int\nsize of object in memory, in bytes",
388   \             "sortText":"z__sizeof__",
389   \             "insertText":"__sizeof__"
390   \          },
391   \          {
392   \             "label":"__str__()",
393   \             "kind":3,
394   \             "detail":"object",
395   \             "documentation":"Return str(self).",
396   \             "sortText":"z__str__",
397   \             "insertText":"__str__"
398   \          },
399   \          {
400   \             "label":"__subclasshook__()",
401   \             "kind":3,
402   \             "detail":"object",
403   \             "documentation":"Abstract classes can override this to customize issubclass().\n\nThis is invoked early on by abc.ABCMeta.__subclasscheck__().\nIt should return True, False or NotImplemented.\u00a0\u00a0If it returns\nNotImplemented, the normal algorithm is used.\u00a0\u00a0Otherwise, it\noverrides the normal algorithm (and the outcome is cached).",
404   \             "sortText":"z__subclasshook__",
405   \             "insertText":"__subclasshook__"
406   \          }
407   \       ]
408   \    }
409   \ })
410
411 Execute(Should handle extra Python completion results correctly):
412   let g:ale_completion_autoimport = 0
413
414   let b:ale_completion_info = {
415   \ 'completion_filter': 'ale#completion#python#CompletionItemFilter',
416   \ 'prefix': 'mig',
417   \}
418
419   AssertEqual
420   \ [
421   \   {'word': 'migrations', 'dup': 0, 'menu': 'xxx', 'info': 'migrations', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
422   \   {'word': 'MigEngine', 'dup': 0, 'menu': 'xxx', 'info': 'mig engine', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
423   \ ],
424   \ ale#completion#ParseLSPCompletions({
425   \   'jsonrpc': '2.0',
426   \   'id': 6,
427   \   'result': {
428   \     'isIncomplete': v:false,
429   \     'items': [
430   \       {
431   \         'label': 'migrations',
432   \         'kind': 3,
433   \         'detail': 'xxx',
434   \         'documentation': 'migrations',
435   \       },
436   \       {
437   \         'label': 'MigEngine',
438   \         'kind': 3,
439   \         'detail': 'xxx',
440   \         'documentation': 'mig engine',
441   \       },
442   \       {
443   \         'label': 'ignore me',
444   \         'kind': 3,
445   \         'detail': 'nope',
446   \         'documentation': 'nope',
447   \       },
448   \     ]
449   \   }
450   \ })
451
452 Execute(Should handle missing keys):
453   let g:ale_completion_autoimport = 0
454
455   AssertEqual
456   \ [
457   \   {'word': 'x', 'dup': 0, 'menu': '', 'info': '', 'kind': 'v', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
458   \ ],
459   \ ale#completion#ParseLSPCompletions({
460   \   'jsonrpc': '2.0',
461   \   'id': 6,
462   \   'result': {
463   \     'isIncomplete': v:false,
464   \     'items': [
465   \       {
466   \         'label': 'x',
467   \       },
468   \     ]
469   \   }
470   \ })
471
472 Execute(Should handle documentation in the markdown format):
473   let g:ale_completion_autoimport = 0
474
475   AssertEqual
476   \ [
477   \   {'word': 'migrations', 'dup': 0, 'menu': 'xxx', 'info': 'Markdown documentation', 'kind': 'f', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
478   \ ],
479   \ ale#completion#ParseLSPCompletions({
480   \   'jsonrpc': '2.0',
481   \   'id': 6,
482   \   'result': {
483   \     'isIncomplete': v:false,
484   \     'items': [
485   \       {
486   \         'label': 'migrations',
487   \         'kind': 3,
488   \         'detail': 'xxx',
489   \         'documentation': {
490   \           'kind': 'markdown',
491   \           'value': 'Markdown documentation',
492   \         },
493   \       },
494   \     ],
495   \   },
496   \ })
497
498 Execute(Should handle completion messages with textEdit objects):
499   let g:ale_completion_autoimport = 0
500
501   AssertEqual
502   \ [
503   \   {'word': 'next_callback', 'dup': 0, 'menu': 'PlayTimeCallback', 'info': '', 'kind': 'v', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
504   \ ],
505   \ ale#completion#ParseLSPCompletions({
506   \   'id': 226,
507   \   'jsonrpc': '2.0',
508   \   'result': {
509   \     'isIncomplete': v:false,
510   \     'items': [
511   \       {
512   \         'detail': 'PlayTimeCallback',
513   \         'filterText': 'next_callback',
514   \         'insertText': 'ignoreme',
515   \         'insertTextFormat': 1,
516   \         'kind': 6,
517   \         'label': ' next_callback',
518   \         'sortText': '3ee19999next_callback',
519   \         'textEdit': {
520   \           'newText': 'next_callback',
521   \           'range': {
522   \             'end': {'character': 13, 'line': 12},
523   \             'start': {'character': 4, 'line': 12},
524   \           },
525   \         },
526   \       },
527   \     ],
528   \   },
529   \ })
530
531 Execute(Should handle completion messages with textEdit objects and no insertTextFormat key):
532   let g:ale_completion_autoimport = 0
533
534   AssertEqual
535   \ [
536   \   {'word': 'next_callback', 'dup': 0, 'menu': 'PlayTimeCallback', 'info': '', 'kind': 'v', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
537   \ ],
538   \ ale#completion#ParseLSPCompletions({
539   \   'id': 226,
540   \   'jsonrpc': '2.0',
541   \   'result': {
542   \     'isIncomplete': v:false,
543   \     'items': [
544   \       {
545   \         'detail': 'PlayTimeCallback',
546   \         'filterText': 'next_callback',
547   \         'insertText': 'ignoreme',
548   \         'kind': 6,
549   \         'label': ' next_callback',
550   \         'sortText': '3ee19999next_callback',
551   \         'textEdit': {
552   \           'newText': 'next_callback',
553   \           'range': {
554   \             'end': {'character': 13, 'line': 12},
555   \             'start': {'character': 4, 'line': 12},
556   \           },
557   \         },
558   \       },
559   \     ],
560   \   },
561   \ })
562
563 Execute(Should handle completion messages with the deprecated insertText attribute):
564   let g:ale_completion_autoimport = 0
565
566   AssertEqual
567   \ [
568   \   {'word': 'next_callback', 'dup': 0, 'menu': 'PlayTimeCallback', 'info': '', 'kind': 'v', 'icase': 1, 'user_data': json_encode({'_ale_completion_item': 1})},
569   \ ],
570   \ ale#completion#ParseLSPCompletions({
571   \   'id': 226,
572   \   'jsonrpc': '2.0',
573   \   'result': {
574   \     'isIncomplete': v:false,
575   \     'items': [
576   \       {
577   \         'detail': 'PlayTimeCallback',
578   \         'filterText': 'next_callback',
579   \         'insertText': 'next_callback',
580   \         'insertTextFormat': 1,
581   \         'kind': 6,
582   \         'label': ' next_callback',
583   \         'sortText': '3ee19999next_callback',
584   \       },
585   \     ],
586   \   },
587   \ })
588
589 Execute(Should handle completion messages with additionalTextEdits when ale_completion_autoimport is turned on):
590   let g:ale_completion_autoimport = 1
591
592   AssertEqual
593   \ [
594   \   {
595   \     'word': 'next_callback',
596   \     'dup': 1,
597   \     'menu': 'PlayTimeCallback',
598   \     'info': '',
599   \     'kind': 'v',
600   \     'icase': 1,
601   \     'user_data': json_encode({
602   \       '_ale_completion_item': 1,
603   \       'code_actions': [
604   \         {
605   \           'description': 'completion',
606   \           'changes': [
607   \             {
608   \               'fileName': expand('#' . bufnr('') . ':p'),
609   \               'textChanges': [
610   \                 {
611   \                   'start': {
612   \                     'line': 11,
613   \                     'offset': 2,
614   \                   },
615   \                   'end': {
616   \                     'line': 13,
617   \                     'offset': 4,
618   \                   },
619   \                   'newText': 'from "module" import next_callback',
620   \                 },
621   \               ],
622   \             },
623   \           ],
624   \         },
625   \       ],
626   \     }),
627   \   },
628   \ ],
629   \ ale#completion#ParseLSPCompletions({
630   \   'id': 226,
631   \   'jsonrpc': '2.0',
632   \   'result': {
633   \     'isIncomplete': v:false,
634   \     'items': [
635   \       {
636   \         'detail': 'PlayTimeCallback',
637   \         'filterText': 'next_callback',
638   \         'insertText': 'next_callback',
639   \         'insertTextFormat': 1,
640   \         'kind': 6,
641   \         'label': ' next_callback',
642   \         'sortText': '3ee19999next_callback',
643   \         'additionalTextEdits': [
644   \           {
645   \             'range': {
646   \               'start': {
647   \                 'line': 10,
648   \                 'character': 1,
649   \               },
650   \               'end': {
651   \                 'line': 12,
652   \                 'character': 3,
653   \               },
654   \             },
655   \             'newText': 'from "module" import next_callback',
656   \           },
657   \         ],
658   \       },
659   \     ],
660   \   },
661   \ })
662
663 Execute(Should not handle completion messages with additionalTextEdits when ale_completion_autoimport is turned off):
664   let g:ale_completion_autoimport = 0
665   let b:ale_completion_info = {'line': 30}
666
667   AssertEqual
668   \ [],
669   \ ale#completion#ParseLSPCompletions({
670   \   'id': 226,
671   \   'jsonrpc': '2.0',
672   \   'result': {
673   \     'isIncomplete': v:false,
674   \     'items': [
675   \       {
676   \         'detail': 'PlayTimeCallback',
677   \         'filterText': 'next_callback',
678   \         'insertText': 'next_callback',
679   \         'insertTextFormat': 1,
680   \         'kind': 6,
681   \         'label': ' next_callback',
682   \         'sortText': '3ee19999next_callback',
683   \         'additionalTextEdits': [
684   \           {
685   \             'range': {
686   \               'start': {
687   \                 'line': 10,
688   \                 'character': 1,
689   \               },
690   \               'end': {
691   \                 'line': 12,
692   \                 'character': 3,
693   \               },
694   \             },
695   \             'newText': 'from "module" import next_callback',
696   \           },
697   \         ],
698   \       },
699   \     ],
700   \   },
701   \ })
702
703 Execute(Should still handle completion messages with empty additionalTextEdits with ale_completion_autoimport turned off):
704   let g:ale_completion_autoimport = 0
705
706   AssertEqual
707   \ [
708   \   {
709   \     'word': 'next_callback',
710   \     'dup': 0,
711   \     'menu': 'PlayTimeCallback',
712   \     'info': '',
713   \     'kind': 'v',
714   \     'icase': 1,
715   \     'user_data': json_encode({'_ale_completion_item': 1}),
716   \   }
717   \ ],
718   \ ale#completion#ParseLSPCompletions({
719   \   'id': 226,
720   \   'jsonrpc': '2.0',
721   \   'result': {
722   \     'isIncomplete': v:false,
723   \     'items': [
724   \       {
725   \         'detail': 'PlayTimeCallback',
726   \         'filterText': 'next_callback',
727   \         'insertText': 'next_callback',
728   \         'insertTextFormat': 1,
729   \         'kind': 6,
730   \         'label': ' next_callback',
731   \         'sortText': '3ee19999next_callback',
732   \         'additionalTextEdits': [],
733   \       },
734   \     ],
735   \   },
736   \ })