/ test / test_linter_defintion_processing.vader
test_linter_defintion_processing.vader
  1  Before:
  2    Save g:ale_root
  3    Save b:ale_root
  4  
  5    let g:ale_root = {}
  6    unlet! b:ale_root
  7  
  8    let g:linter = {}
  9  
 10  After:
 11    unlet g:linter
 12  
 13  Execute (PreProcess should throw when the linter object is not a Dictionary):
 14    AssertThrows call ale#linter#PreProcess('testft', '')
 15    AssertEqual 'The linter object must be a Dictionary', g:vader_exception
 16  
 17  Execute (PreProcess should throw when there is no name):
 18    AssertThrows call ale#linter#PreProcess('testft', {
 19    \ 'callback': 'SomeFunction',
 20    \ 'executable': 'echo',
 21    \ 'command': 'echo',
 22    \})
 23    AssertEqual '`name` must be defined to name the linter', g:vader_exception
 24  
 25  Execute (PreProcess should throw when there is no callback):
 26    AssertThrows call ale#linter#PreProcess('testft', {
 27    \ 'name': 'foo',
 28    \ 'executable': 'echo',
 29    \ 'command': 'echo',
 30    \})
 31    AssertEqual '`callback` must be defined with a callback to accept output', g:vader_exception
 32  
 33  Execute (PreProcess should throw when then callback is not a function):
 34    AssertThrows call ale#linter#PreProcess('testft', {
 35    \ 'name': 'foo',
 36    \ 'callback': 1,
 37    \ 'executable': 'echo',
 38    \ 'command': 'echo',
 39    \})
 40    AssertEqual '`callback` must be defined with a callback to accept output', g:vader_exception
 41  
 42  Execute (PreProcess should throw when there is no executable):
 43    AssertThrows call ale#linter#PreProcess('testft', {
 44    \ 'name': 'foo',
 45    \ 'callback': 'SomeFunction',
 46    \ 'command': 'echo',
 47    \})
 48    AssertEqual '`executable` must be defined', g:vader_exception
 49  
 50  Execute (PreProcess should throw when executable is not a string):
 51    AssertThrows call ale#linter#PreProcess('testft', {
 52    \ 'name': 'foo',
 53    \ 'callback': 'SomeFunction',
 54    \ 'executable': 123,
 55    \ 'command': 'echo',
 56    \})
 57    AssertEqual '`executable` must be a String or Function if defined', g:vader_exception
 58  
 59  Execute (PreProcess should allow executable to be a callback):
 60    call ale#linter#PreProcess('testft', {
 61    \ 'name': 'foo',
 62    \ 'callback': 'SomeFunction',
 63    \ 'executable': function('type'),
 64    \ 'command': 'echo',
 65    \})
 66  
 67  Execute (PreProcess should throw when there is no command):
 68    AssertThrows call ale#linter#PreProcess('testft', {
 69    \ 'name': 'foo',
 70    \ 'callback': 'SomeFunction',
 71    \ 'executable': 'echo',
 72    \})
 73    AssertEqual '`command` must be defined', g:vader_exception
 74  
 75  Execute (PreProcess should throw when command is not a string):
 76    AssertThrows call ale#linter#PreProcess('testft', {
 77    \ 'name': 'foo',
 78    \ 'callback': 'SomeFunction',
 79    \ 'executable': 'echo',
 80    \ 'command': [],
 81    \})
 82    AssertEqual '`command` must be a String or Function if defined', g:vader_exception
 83  
 84  Execute (PreProcess should allow command to be a callback):
 85    call ale#linter#PreProcess('testft', {
 86    \ 'name': 'foo',
 87    \ 'callback': 'SomeFunction',
 88    \ 'executable': 'echo',
 89    \ 'command': function('type'),
 90    \})
 91  
 92  Execute (PreProcess should throw when cwd is not a string):
 93    AssertThrows call ale#linter#PreProcess('testft', {
 94    \ 'name': 'foo',
 95    \ 'callback': 'SomeFunction',
 96    \ 'executable': 'echo',
 97    \ 'cwd': [],
 98    \ 'command': 'echo',
 99    \})
100    AssertEqual '`cwd` must be a String or Function if defined', g:vader_exception
101  
102  Execute (PreProcess should allow cwd to be a callback):
103    call ale#linter#PreProcess('testft', {
104    \ 'name': 'foo',
105    \ 'callback': 'SomeFunction',
106    \ 'executable': 'echo',
107    \ 'cwd': function('type'),
108    \ 'command': 'echo',
109    \})
110  
111  Execute (PreProcess should allow cwd to be a string):
112    call ale#linter#PreProcess('testft', {
113    \ 'name': 'foo',
114    \ 'callback': 'SomeFunction',
115    \ 'executable': 'echo',
116    \ 'cwd': '/foo/bar',
117    \ 'command': 'echo',
118    \})
119  
120  Execute (PreProcess should when the output stream isn't a valid string):
121    AssertThrows call ale#linter#PreProcess('testft', {
122    \ 'name': 'foo',
123    \ 'callback': 'SomeFunction',
124    \ 'executable': 'echo',
125    \ 'command': 'echo',
126    \ 'output_stream': 'xxx',
127    \})
128    AssertEqual "`output_stream` must be 'stdout', 'stderr', or 'both'", g:vader_exception
129  
130  Execute (PreProcess should not throw when everything is correct):
131    call ale#linter#PreProcess('testft', {
132    \ 'name': 'foo',
133    \ 'callback': 'SomeFunction',
134    \ 'executable': 'echo',
135    \ 'command': 'echo',
136    \})
137  
138  Execute (PreProcess should accept an stdout output_stream):
139    call ale#linter#PreProcess('testft', {
140    \ 'name': 'foo',
141    \ 'callback': 'SomeFunction',
142    \ 'executable': 'echo',
143    \ 'command': 'echo',
144    \ 'output_stream': 'stdout',
145    \})
146  
147  Execute (PreProcess should accept an stderr output_stream):
148    call ale#linter#PreProcess('testft', {
149    \ 'name': 'foo',
150    \ 'callback': 'SomeFunction',
151    \ 'executable': 'echo',
152    \ 'command': 'echo',
153    \ 'output_stream': 'stderr',
154    \})
155  
156  Execute (PreProcess should accept a 'both' output_stream):
157    call ale#linter#PreProcess('testft', {
158    \ 'name': 'foo',
159    \ 'callback': 'SomeFunction',
160    \ 'executable': 'echo',
161    \ 'command': 'echo',
162    \ 'output_stream': 'both',
163    \})
164  
165  Execute(PreProcess should process the read_buffer option correctly):
166    let g:linter = {
167    \ 'name': 'x',
168    \ 'callback': 'x',
169    \ 'executable': 'x',
170    \ 'command': 'x',
171    \ 'read_buffer': '0',
172    \}
173  
174    AssertThrows call ale#linter#PreProcess('testft', g:linter)
175    AssertEqual '`read_buffer` must be `0` or `1`', g:vader_exception
176  
177    let g:linter.read_buffer = 0
178  
179    call ale#linter#PreProcess('testft', g:linter)
180  
181    let g:linter.read_buffer = 1
182  
183    call ale#linter#PreProcess('testft', g:linter)
184  
185  Execute(PreProcess should set a default value for read_buffer):
186    let g:linter = {
187    \ 'name': 'x',
188    \ 'callback': 'x',
189    \ 'executable': 'x',
190    \ 'command': 'x',
191    \}
192  
193    AssertEqual 1, ale#linter#PreProcess('testft', g:linter).read_buffer
194  
195  Execute(PreProcess should process the lint_file option correctly):
196    let g:linter = {
197    \ 'name': 'x',
198    \ 'callback': 'x',
199    \ 'executable': 'x',
200    \ 'command': 'x',
201    \ 'lint_file': 'x',
202    \}
203  
204    AssertThrows call ale#linter#PreProcess('testft', g:linter)
205    AssertEqual '`lint_file` must be `0`, `1`, or a Function', g:vader_exception
206  
207    let g:linter.lint_file = 0
208  
209    AssertEqual 0, ale#linter#PreProcess('testft', g:linter).lint_file
210    " The default for read_buffer should be 1 when lint_file is 0
211    AssertEqual 1, ale#linter#PreProcess('testft', g:linter).read_buffer
212  
213    let g:linter.lint_file = 1
214  
215    AssertEqual 1, ale#linter#PreProcess('testft', g:linter).lint_file
216    " The default for read_buffer should still be 1
217    AssertEqual 1, ale#linter#PreProcess('testft', g:linter).read_buffer
218  
219    let g:linter.read_buffer = 1
220  
221    " We should be able to set `read_buffer` and `lint_file` at the same time.
222    AssertEqual 1, ale#linter#PreProcess('testft', g:linter).read_buffer
223  
224    let g:linter.lint_file = function('type')
225  
226    Assert type(ale#linter#PreProcess('testft', g:linter).lint_file) is v:t_func
227  
228  Execute(PreProcess should set a default value for lint_file):
229    let g:linter = {
230    \ 'name': 'x',
231    \ 'callback': 'x',
232    \ 'executable': 'x',
233    \ 'command': 'x',
234    \}
235  
236    AssertEqual 0, ale#linter#PreProcess('testft', g:linter).lint_file
237  
238  Execute(PreProcess should set a default value for aliases):
239    let g:linter = {
240    \ 'name': 'x',
241    \ 'callback': 'x',
242    \ 'executable': 'x',
243    \ 'command': 'x',
244    \}
245  
246    AssertEqual [], ale#linter#PreProcess('testft', g:linter).aliases
247  
248  Execute(PreProcess should complain about invalid `aliases` values):
249    let g:linter = {
250    \ 'name': 'x',
251    \ 'callback': 'x',
252    \ 'executable': 'x',
253    \ 'command': 'x',
254    \ 'aliases': 'foo',
255    \}
256  
257    AssertThrows call ale#linter#PreProcess('testft', g:linter)
258    AssertEqual '`aliases` must be a List of String values', g:vader_exception
259  
260    let g:linter.aliases = [1]
261  
262    AssertThrows call ale#linter#PreProcess('testft', g:linter)
263    AssertEqual '`aliases` must be a List of String values', g:vader_exception
264  
265  Execute(PreProcess should accept `aliases` lists):
266    let g:linter = {
267    \ 'name': 'x',
268    \ 'callback': 'x',
269    \ 'executable': 'x',
270    \ 'command': 'x',
271    \ 'aliases': [],
272    \}
273  
274    AssertEqual [], ale#linter#PreProcess('testft', g:linter).aliases
275  
276    let g:linter.aliases = ['foo', 'bar']
277  
278    AssertEqual ['foo', 'bar'], ale#linter#PreProcess('testft', g:linter).aliases
279  
280  Execute(PreProcess should accept tsserver LSP configuration):
281    let g:linter = {
282    \ 'name': 'x',
283    \ 'executable': 'x',
284    \ 'command': 'x',
285    \ 'lsp': 'tsserver',
286    \ 'language': 'x',
287    \ 'project_root': 'x',
288    \}
289  
290    AssertEqual 'tsserver', ale#linter#PreProcess('testft', g:linter).lsp
291  
292  Execute(PreProcess should accept stdio LSP configuration):
293    let g:linter = {
294    \ 'name': 'x',
295    \ 'executable': 'x',
296    \ 'command': 'x',
297    \ 'lsp': 'stdio',
298    \ 'language': 'x',
299    \ 'project_root': 'x',
300    \}
301  
302    AssertEqual 'stdio', ale#linter#PreProcess('testft', g:linter).lsp
303  
304  Execute(PreProcess should accept LSP server configurations):
305    let g:linter = {
306    \ 'name': 'x',
307    \ 'lsp': 'socket',
308    \ 'address': 'X',
309    \ 'language': 'foobar',
310    \ 'project_root': 'x',
311    \}
312  
313    AssertEqual 'socket', ale#linter#PreProcess('testft', g:linter).lsp
314  
315  Execute(PreProcess should accept let you specify the `language` as a Function):
316    let g:linter = {
317    \ 'name': 'x',
318    \ 'lsp': 'socket',
319    \ 'address': 'X',
320    \ 'language': {-> 'foobar'},
321    \ 'project_root': 'x',
322    \}
323  
324    AssertEqual 'foobar', ale#linter#PreProcess('testft', g:linter).language(bufnr(''))
325  
326  Execute(PreProcess should complain about invalid language values):
327    let g:linter = {
328    \ 'name': 'x',
329    \ 'lsp': 'socket',
330    \ 'address': 'X',
331    \ 'language': 0,
332    \ 'project_root': 'x',
333    \}
334  
335    AssertThrows call ale#linter#PreProcess('testft', g:linter)
336    AssertEqual '`language` must be a String or Function if defined', g:vader_exception
337  
338  Execute(PreProcess should use the filetype as the language string by default):
339    let g:linter = {
340    \ 'name': 'x',
341    \ 'lsp': 'socket',
342    \ 'address': 'X',
343    \ 'project_root': 'x',
344    \}
345  
346    AssertEqual 'testft', ale#linter#PreProcess('testft', g:linter).language
347  
348  Execute(PreProcess should require an `address` for LSP socket configurations):
349    let g:linter = {
350    \ 'name': 'x',
351    \ 'lsp': 'socket',
352    \}
353  
354    AssertThrows call ale#linter#PreProcess('testft', g:linter)
355    AssertEqual '`address` must be defined for getting the LSP address', g:vader_exception
356  
357  Execute(PreProcess should complain about `address` for non-LSP linters):
358    let g:linter = {
359    \ 'name': 'x',
360    \ 'callback': 'SomeFunction',
361    \ 'executable': 'echo',
362    \ 'command': 'echo',
363    \ 'address': 'X',
364    \}
365  
366    AssertThrows call ale#linter#PreProcess('testft', g:linter)
367    AssertEqual '`address` cannot be used when lsp != ''socket''', g:vader_exception
368  
369  Execute(PreProcess accept `address` as a String):
370    let g:linter = ale#linter#PreProcess('testft', {
371    \ 'name': 'x',
372    \ 'lsp': 'socket',
373    \ 'address': 'foo:123',
374    \ 'language': 'x',
375    \ 'project_root': 'x',
376    \})
377  
378    AssertEqual 'foo:123', ale#linter#GetAddress(0, g:linter)
379  
380  Execute(PreProcess accept address as a Function):
381    let g:linter = ale#linter#PreProcess('testft', {
382    \ 'name': 'x',
383    \ 'lsp': 'socket',
384    \ 'address': {-> 'foo:123'},
385    \ 'language': 'x',
386    \ 'project_root': 'x',
387    \})
388  
389    AssertEqual 'foo:123', ale#linter#GetAddress(0, g:linter)
390  
391  Execute(PreProcess should complain about invalid address values):
392    AssertThrows call ale#linter#PreProcess('testft', {
393    \ 'name': 'x',
394    \ 'lsp': 'socket',
395    \ 'address': 0,
396    \ 'language': 'x',
397    \ 'project_root': 'x',
398    \})
399    AssertEqual '`address` must be a String or Function if defined', g:vader_exception
400  
401  Execute(PreProcess should allow the `project_root` to be set as a String):
402    let g:linter = ale#linter#PreProcess('testft', {
403    \ 'name': 'x',
404    \ 'lsp': 'socket',
405    \ 'address': 'foo:123',
406    \ 'language': 'x',
407    \ 'project_root': '/foo/bar',
408    \})
409  
410    AssertEqual '/foo/bar', ale#lsp_linter#FindProjectRoot(0, g:linter)
411  
412  Execute(PreProcess should `project_root` be set as a Function):
413    let g:linter = ale#linter#PreProcess('testft', {
414    \ 'name': 'x',
415    \ 'lsp': 'socket',
416    \ 'address': 'foo:123',
417    \ 'language': 'x',
418    \ 'project_root': {-> '/foo/bar'},
419    \})
420  
421    AssertEqual '/foo/bar', ale#lsp_linter#FindProjectRoot(0, g:linter)
422  
423  Execute(PreProcess should complain when `project_root` is invalid):
424    AssertThrows call ale#linter#PreProcess('testft', {
425    \ 'name': 'x',
426    \ 'lsp': 'socket',
427    \ 'address': 'foo:123',
428    \ 'language': 'x',
429    \ 'project_root': 0,
430    \})
431    AssertEqual '`project_root` must be a String or Function', g:vader_exception
432  
433  Execute(PreProcess should throw when `initialization_options` is not a Dictionary or callback):
434    AssertThrows call ale#linter#PreProcess('testft', {
435    \ 'name': 'foo',
436    \ 'lsp': 'socket',
437    \ 'address': 'X',
438    \ 'language': 'x',
439    \ 'project_root': 'x',
440    \ 'initialization_options': 0,
441    \})
442    AssertEqual '`initialization_options` must be a Dictionary or Function if defined', g:vader_exception
443  
444  Execute(PreProcess should accept `initialization_options` as a Dictionary):
445    let g:linter = ale#linter#PreProcess('testft', {
446    \ 'name': 'foo',
447    \ 'lsp': 'socket',
448    \ 'address': 'X',
449    \ 'language': 'x',
450    \ 'project_root': 'x',
451    \ 'initialization_options': {'foo': v:true},
452    \})
453  
454    AssertEqual {'foo': v:true}, ale#lsp_linter#GetOptions(0, g:linter)
455  
456  Execute(PreProcess should accept `initialization_options` as a Function):
457    let g:linter = ale#linter#PreProcess('testft', {
458    \ 'name': 'foo',
459    \ 'lsp': 'socket',
460    \ 'address': 'X',
461    \ 'language': 'x',
462    \ 'project_root': 'x',
463    \ 'initialization_options': {-> {'foo': v:true}},
464    \})
465  
466    AssertEqual {'foo': v:true}, ale#lsp_linter#GetOptions(0, g:linter)
467  
468  Execute(PreProcess should accept `lsp_config` as a Dictionary):
469    let g:linter = {
470    \ 'name': 'x',
471    \ 'lsp': 'socket',
472    \ 'address': 'X',
473    \ 'language': 'x',
474    \ 'project_root': 'x',
475    \ 'lsp_config': {'foo': 'bar'},
476    \}
477  
478    AssertEqual {'foo': 'bar'}, ale#lsp_linter#GetConfig(0, g:linter)
479  
480  Execute(PreProcess should accept `lsp_config` as a Function):
481    let g:linter = {
482    \ 'name': 'x',
483    \ 'lsp': 'socket',
484    \ 'address': 'X',
485    \ 'language': 'x',
486    \ 'project_root': 'x',
487    \ 'lsp_config': {-> {'foo': 'bar'}},
488    \}
489  
490    AssertEqual {'foo': 'bar'}, ale#lsp_linter#GetConfig(0, g:linter)
491  
492  Execute(PreProcess should throw when `lsp_config` is not a Dictionary or Function):
493    AssertThrows call ale#linter#PreProcess('testft', {
494    \ 'name': 'foo',
495    \ 'lsp': 'socket',
496    \ 'address': 'X',
497    \ 'language': 'x',
498    \ 'project_root': 'x',
499    \ 'lsp_config': 'x',
500    \})
501    AssertEqual '`lsp_config` must be a Dictionary or Function if defined', g:vader_exception