summaryrefslogtreecommitdiff
path: root/test/lsp/test_lsp_custom_request.vader
blob: 04f044afc39edf6f69f95a7e3af327f216ad0e98 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
Before:
  runtime autoload/ale/linter.vim
  runtime autoload/ale/lsp.vim
  runtime autoload/ale/lsp_linter.vim

  let g:address = 'ccls_address'
  let g:conn_id = -1
  let g:executable = 'ccls'
  let g:executable_or_address = ''
  let g:linter_name = 'ccls'
  let g:magic_number = 42
  let g:no_result = 0
  let g:message_list = []
  let g:message_id = 1
  let g:method = '$ccls/call'
  let g:parameters = {}
  let g:project_root = '/project/root'
  let g:response = ''
  let g:return_value = -1

  let g:linter_list = [{
  \   'output_stream': 'stdout',
  \   'lint_file': 0,
  \   'language': 'cpp',
  \   'name': g:linter_name,
  \   'project_root': {b -> g:project_root},
  \   'aliases': [],
  \   'language_callback': {b -> 'cpp'},
  \   'read_buffer': 1,
  \   'command': '%e'
  \ }]

  let g:callback_result = g:no_result

  " Encode dictionary to jsonrpc
  function! Encode(obj) abort
    let l:body = json_encode(a:obj)
    return 'Content-Length: ' . strlen(l:body) . "\r\n\r\n" . l:body
  endfunction

  " Replace the StartLSP function to mock an LSP linter
  function! ale#lsp_linter#StartLSP(buffer, linter, Callback) abort
    let g:conn_id = ale#lsp#Register(g:executable_or_address, g:project_root, {})
    call ale#lsp#MarkDocumentAsOpen(g:conn_id, a:buffer)
    call ale#lsp#HandleMessage(g:conn_id, Encode({'method': 'initialize'}))

    let l:details = {
    \ 'command': g:executable,
    \ 'buffer': a:buffer,
    \ 'connection_id': g:conn_id,
    \ 'project_root': g:project_root,
    \}

    call ale#lsp_linter#OnInit(a:linter, l:details, a:Callback)
  endfunction

  " Dummy callback
  function! Callback(response) abort
    let g:callback_result = a:response.result.value
  endfunction

  " Replace the GetAll function to mock an LSP linter
  function! ale#linter#GetAll(filetype) abort
    return g:linter_list
  endfunction

  " Replace the Send function to mock an LSP linter
  function! ale#lsp#Send(conn_id, message) abort
    call add(g:message_list, a:message)
    return g:message_id
  endfunction

  " Code for a test case
  function! TestCase(is_notification) abort
    " Test sending a custom request
    let g:return_value = ale#lsp_linter#SendRequest(
    \  bufnr('%'),
    \  g:linter_name,
    \  [a:is_notification, g:method, g:parameters],
    \  function('Callback'))

    Assert index(g:message_list, [a:is_notification, g:method, g:parameters]) >= 0

    " Mock an incoming response to the request
    let g:response = Encode({
    \  'id': g:message_id,
    \  'jsonrpc': '2.0',
    \  'result': {'value': g:magic_number}
    \ })
    call ale#lsp#HandleMessage(g:conn_id, g:response)

    AssertEqual
    \ a:is_notification ? g:no_result : g:magic_number,
    \ g:callback_result
  endfunction

After:
  if g:conn_id isnot v:null
    call ale#lsp#RemoveConnectionWithID(g:conn_id)
  endif

  unlet! g:callback_result
  unlet! g:conn_id
  unlet! g:executable
  unlet! g:is_notification
  unlet! g:linter_name
  unlet! g:magic_number
  unlet! g:message_list
  unlet! g:message_id
  unlet! g:method
  unlet! g:no_result
  unlet! g:parameters
  unlet! g:project_root
  unlet! g:response
  unlet! g:return_value

  delfunction Encode
  delfunction Callback
  delfunction TestCase

  runtime autoload/ale/linter.vim
  runtime autoload/ale/lsp.vim
  runtime autoload/ale/lsp_linter.vim

Given cpp(Empty cpp file):
Execute(Test custom request to server identified by executable):
  let g:executable_or_address = g:executable
  let g:linter_list[0].executable = {b -> g:executable}
  let g:linter_list[0].lsp = 'stdio'
  let g:is_notification = 0

  call TestCase(g:is_notification)

Given cpp(Empty cpp file):
Execute(Test custom notification to server identified by executable):
  let g:executable_or_address = g:executable
  let g:linter_list[0].executable = {b -> g:executable}
  let g:linter_list[0].lsp = 'stdio'
  let g:is_notification = 1

  call TestCase(g:is_notification)

Given cpp(Empty cpp file):
Execute(Test custom request to server identified by address):
  let g:executable_or_address = g:address
  let g:linter_list[0].address = {b -> g:address}
  let g:linter_list[0].lsp = 'socket'
  let g:is_notification = 0

  call TestCase(g:is_notification)

Given cpp(Empty cpp file):
Execute(Test custom notification to server identified by address):
  let g:executable_or_address = g:address
  let g:linter_list[0].address = {b -> g:address}
  let g:linter_list[0].lsp = 'socket'
  let g:is_notification = 1

  call TestCase(g:is_notification)