@@ -5,12 +5,23 @@ describe("Tool: get_diagnostics", function()
5
5
6
6
before_each (function ()
7
7
package.loaded [" claudecode.tools.get_diagnostics" ] = nil
8
+ package.loaded [" claudecode.logger" ] = nil
9
+
10
+ -- Mock the logger module
11
+ package.loaded [" claudecode.logger" ] = {
12
+ debug = function () end ,
13
+ error = function () end ,
14
+ info = function () end ,
15
+ warn = function () end ,
16
+ }
17
+
8
18
get_diagnostics_handler = require (" claudecode.tools.get_diagnostics" ).handler
9
19
10
20
_G .vim = _G .vim or {}
11
21
_G .vim .lsp = _G .vim .lsp or {} -- Ensure vim.lsp exists for the check
12
22
_G .vim .diagnostic = _G .vim .diagnostic or {}
13
23
_G .vim .api = _G .vim .api or {}
24
+ _G .vim .fn = _G .vim .fn or {}
14
25
15
26
-- Default mocks
16
27
_G .vim .diagnostic .get = spy .new (function ()
@@ -19,12 +30,25 @@ describe("Tool: get_diagnostics", function()
19
30
_G .vim .api .nvim_buf_get_name = spy .new (function (bufnr )
20
31
return " /path/to/file_for_buf_" .. tostring (bufnr ) .. " .lua"
21
32
end )
33
+ _G .vim .fn .json_encode = spy .new (function (obj )
34
+ return vim .inspect (obj ) -- Use vim.inspect as a simple serialization
35
+ end )
36
+ _G .vim .fn .bufnr = spy .new (function (filepath )
37
+ -- Mock buffer lookup
38
+ if filepath == " /test/file.lua" then
39
+ return 1
40
+ end
41
+ return - 1 -- File not open
42
+ end )
22
43
end )
23
44
24
45
after_each (function ()
25
46
package.loaded [" claudecode.tools.get_diagnostics" ] = nil
47
+ package.loaded [" claudecode.logger" ] = nil
26
48
_G .vim .diagnostic .get = nil
27
49
_G .vim .api .nvim_buf_get_name = nil
50
+ _G .vim .fn .json_encode = nil
51
+ _G .vim .fn .bufnr = nil
28
52
-- Note: We don't nullify _G.vim.lsp or _G.vim.diagnostic entirely
29
53
-- as they are checked for existence.
30
54
end )
@@ -33,14 +57,14 @@ describe("Tool: get_diagnostics", function()
33
57
local success , result = pcall (get_diagnostics_handler , {})
34
58
expect (success ).to_be_true ()
35
59
expect (result ).to_be_table ()
36
- expect (result .diagnostics ).to_be_table ()
37
- expect (# result .diagnostics ).to_be (0 )
38
- assert .spy (_G .vim .diagnostic .get ).was_called_with (0 )
60
+ expect (result .content ).to_be_table ()
61
+ expect (# result .content ).to_be (0 )
62
+ assert .spy (_G .vim .diagnostic .get ).was_called_with ()
39
63
end )
40
64
41
65
it (" should return formatted diagnostics if available" , function ()
42
66
local mock_diagnostics = {
43
- { bufnr = 1 , lnum = 10 , col = 5 , severity = 1 , message = " Error message 1" , source = " linter1" },
67
+ { bufnr = 1 , lnum = 10 , col = 5 , severity = 1 , message = " Error message 1" , source = " linter1" },
44
68
{ bufnr = 2 , lnum = 20 , col = 15 , severity = 2 , message = " Warning message 2" , source = " linter2" },
45
69
}
46
70
_G .vim .diagnostic .get = spy .new (function ()
@@ -49,27 +73,32 @@ describe("Tool: get_diagnostics", function()
49
73
50
74
local success , result = pcall (get_diagnostics_handler , {})
51
75
expect (success ).to_be_true ()
52
- expect (result .diagnostics ).to_be_table ()
53
- expect (# result .diagnostics ).to_be (2 )
76
+ expect (result .content ).to_be_table ()
77
+ expect (# result .content ).to_be (2 )
54
78
55
- expect (result .diagnostics [1 ].file ).to_be (" /path/to/file_for_buf_1.lua" )
56
- expect (result .diagnostics [1 ].line ).to_be (10 )
57
- expect (result .diagnostics [1 ].character ).to_be (5 )
58
- expect (result .diagnostics [1 ].severity ).to_be (1 )
59
- expect (result .diagnostics [1 ].message ).to_be (" Error message 1" )
60
- expect (result .diagnostics [1 ].source ).to_be (" linter1" )
79
+ -- Check that results are MCP content items
80
+ expect (result .content [1 ].type ).to_be (" text" )
81
+ expect (result .content [2 ].type ).to_be (" text" )
61
82
62
- expect (result .diagnostics [2 ].file ).to_be (" /path/to/file_for_buf_2.lua" )
63
- expect (result .diagnostics [2 ].severity ).to_be (2 )
64
- expect (result .diagnostics [2 ].message ).to_be (" Warning message 2" )
83
+ -- Verify JSON encoding was called with correct structure
84
+ assert .spy (_G .vim .fn .json_encode ).was_called (2 )
85
+
86
+ -- Check the first diagnostic was encoded with 1-indexed values
87
+ local first_call_args = _G .vim .fn .json_encode .calls [1 ].vals [1 ]
88
+ expect (first_call_args .filePath ).to_be (" /path/to/file_for_buf_1.lua" )
89
+ expect (first_call_args .line ).to_be (11 ) -- 10 + 1 for 1-indexing
90
+ expect (first_call_args .character ).to_be (6 ) -- 5 + 1 for 1-indexing
91
+ expect (first_call_args .severity ).to_be (1 )
92
+ expect (first_call_args .message ).to_be (" Error message 1" )
93
+ expect (first_call_args .source ).to_be (" linter1" )
65
94
66
95
assert .spy (_G .vim .api .nvim_buf_get_name ).was_called_with (1 )
67
96
assert .spy (_G .vim .api .nvim_buf_get_name ).was_called_with (2 )
68
97
end )
69
98
70
99
it (" should filter out diagnostics with no file path" , function ()
71
100
local mock_diagnostics = {
72
- { bufnr = 1 , lnum = 10 , col = 5 , severity = 1 , message = " Error message 1" , source = " linter1" },
101
+ { bufnr = 1 , lnum = 10 , col = 5 , severity = 1 , message = " Error message 1" , source = " linter1" },
73
102
{ bufnr = 99 , lnum = 20 , col = 15 , severity = 2 , message = " Warning message 2" , source = " linter2" }, -- This one will have no path
74
103
}
75
104
_G .vim .diagnostic .get = spy .new (function ()
@@ -87,8 +116,12 @@ describe("Tool: get_diagnostics", function()
87
116
88
117
local success , result = pcall (get_diagnostics_handler , {})
89
118
expect (success ).to_be_true ()
90
- expect (# result .diagnostics ).to_be (1 )
91
- expect (result .diagnostics [1 ].file ).to_be (" /path/to/file1.lua" )
119
+ expect (# result .content ).to_be (1 )
120
+
121
+ -- Verify only the diagnostic with a file path was included
122
+ assert .spy (_G .vim .fn .json_encode ).was_called (1 )
123
+ local encoded_args = _G .vim .fn .json_encode .calls [1 ].vals [1 ]
124
+ expect (encoded_args .filePath ).to_be (" /path/to/file1.lua" )
92
125
end )
93
126
94
127
it (" should error if vim.diagnostic.get is not available" , function ()
@@ -120,4 +153,66 @@ describe("Tool: get_diagnostics", function()
120
153
expect (success ).to_be_false ()
121
154
expect (err .code ).to_be (- 32000 )
122
155
end )
156
+
157
+ it (" should filter diagnostics by URI when provided" , function ()
158
+ local mock_diagnostics = {
159
+ { bufnr = 1 , lnum = 10 , col = 5 , severity = 1 , message = " Error in file1" , source = " linter1" },
160
+ }
161
+ _G .vim .diagnostic .get = spy .new (function (bufnr )
162
+ if bufnr == 1 then
163
+ return mock_diagnostics
164
+ end
165
+ return {}
166
+ end )
167
+ _G .vim .api .nvim_buf_get_name = spy .new (function (bufnr )
168
+ if bufnr == 1 then
169
+ return " /test/file.lua"
170
+ end
171
+ return " "
172
+ end )
173
+
174
+ local success , result = pcall (get_diagnostics_handler , { uri = " file:///test/file.lua" })
175
+ expect (success ).to_be_true ()
176
+ expect (# result .content ).to_be (1 )
177
+
178
+ -- Should have called vim.diagnostic.get with specific buffer
179
+ assert .spy (_G .vim .diagnostic .get ).was_called_with (1 )
180
+ assert .spy (_G .vim .fn .bufnr ).was_called_with (" /test/file.lua" )
181
+ end )
182
+
183
+ it (" should error for URI of unopened file" , function ()
184
+ _G .vim .fn .bufnr = spy .new (function ()
185
+ return - 1 -- File not open
186
+ end )
187
+
188
+ local success , err = pcall (get_diagnostics_handler , { uri = " file:///unknown/file.lua" })
189
+ expect (success ).to_be_false ()
190
+ expect (err ).to_be_table ()
191
+ expect (err .code ).to_be (- 32001 )
192
+ expect (err .message ).to_be (" File not open in buffer" )
193
+ assert_contains (err .data , " File must be open in Neovim to retrieve diagnostics: /unknown/file.lua" )
194
+
195
+ -- Should have checked for buffer but not called vim.diagnostic.get
196
+ assert .spy (_G .vim .fn .bufnr ).was_called_with (" /unknown/file.lua" )
197
+ assert .spy (_G .vim .diagnostic .get ).was_not_called ()
198
+ end )
199
+
200
+ it (" should handle URI without file:// prefix" , function ()
201
+ _G .vim .fn .bufnr = spy .new (function (filepath )
202
+ if filepath == " /test/file.lua" then
203
+ return 1
204
+ end
205
+ return - 1
206
+ end )
207
+ _G .vim .diagnostic .get = spy .new (function ()
208
+ return {}
209
+ end )
210
+
211
+ local success , result = pcall (get_diagnostics_handler , { uri = " /test/file.lua" })
212
+ expect (success ).to_be_true ()
213
+
214
+ -- Should have used the path directly
215
+ assert .spy (_G .vim .fn .bufnr ).was_called_with (" /test/file.lua" )
216
+ assert .spy (_G .vim .diagnostic .get ).was_called_with (1 )
217
+ end )
123
218
end )
0 commit comments