@@ -298,15 +298,11 @@ function! s:run.process(Callback, bufnr, tests, response) abort
298298 \ ' locations' : []
299299 \}
300300 for result in a: response .Body.Results
301- " Strip method signature from test method fullname
302- let fullname = substitute (result.MethodName, ' (.*)$' , ' ' , ' ' )
303- " Strip namespace and classname from test method name
304- let name = substitute (result.MethodName, ' ^.*\.' , ' ' , ' ' )
305301 let location = {
306302 \ ' bufnr' : a: bufnr ,
307- \ ' fullname' : fullname ,
303+ \ ' fullname' : result.MethodName ,
308304 \ ' filename' : bufname (a: bufnr ),
309- \ ' name' : name
305+ \ ' name' : substitute (result.MethodName, ' ^.*\. ' , ' ' , ' ' )
310306 \}
311307 let locations = [location]
312308 " Write any standard output to message-history
@@ -393,22 +389,44 @@ function! s:utils.capabilities() abort
393389endfunction
394390
395391" Find all of the test methods in a CodeStructure response
396- function ! s: utils .extractTests (codeElements) abort
392+ function ! s: utils .extractTests (bufnr , codeElements) abort
397393 if type (a: codeElements ) != type ([]) | return [] | endif
394+ let filename = fnamemodify (bufname (a: bufnr ), ' :p' )
395+ let testlines = map (
396+ \ filter (
397+ \ copy (OmniSharp#GetHost (a: bufnr ).project.tests),
398+ \ {_,dt - > dt.CodeFilePath == # filename}),
399+ \ {_,dt - > dt.LineNumber})
398400 let tests = []
399401 for element in a: codeElements
400402 if has_key (element, ' Properties' )
401403 \ && type (element.Properties) == type ({})
402404 \ && has_key (element.Properties, ' testMethodName' )
403405 \ && has_key (element.Properties, ' testFramework' )
404- call add (tests, {
405- \ ' name' : element.Properties.testMethodName,
406- \ ' framework' : element.Properties.testFramework,
407- \ ' range' : element.Ranges.full,
408- \ ' nameRange' : element.Ranges.name,
409- \} )
406+ " Compare with project discovered tests. Note that test discovery may
407+ " include a test multiple times, if the test can be run with different
408+ " arguments (e.g. NUnit TestCaseSource)
409+
410+ " Discovered test line numbers begin at the first line of code, not the
411+ " line containing the test name, so when the method opening brace is not
412+ " on the same line as the test method name, the line numbers will not
413+ " match. We therefore search ahead for the closest line number, and use
414+ " that.
415+ let testStart = element.Ranges.name.Start.Line
416+ let testStart = min (filter (copy (testlines), {_,l - > l >= testStart}))
417+ for dt in OmniSharp#GetHost (a: bufnr ).project.tests
418+ if dt.CodeFilePath == # filename && dt.LineNumber == testStart
419+ " \ 'name': element.Properties.testMethodName,
420+ call add (tests, {
421+ \ ' name' : dt.FullyQualifiedName,
422+ \ ' framework' : element.Properties.testFramework,
423+ \ ' range' : element.Ranges.full,
424+ \ ' nameRange' : element.Ranges.name,
425+ \} )
426+ endif
427+ endfor
410428 endif
411- call extend (tests, self .extractTests (get (element, ' Children' , [])))
429+ call extend (tests, self .extractTests (a: bufnr , get (element, ' Children' , [])))
412430 endfor
413431 return tests
414432endfunction
@@ -429,12 +447,13 @@ function! s:utils.findTest(tests, testName) abort
429447 return 0
430448endfunction
431449
432- " For the given buffers, fetch the project structures, then fetch the buffer
433- " code structures. All operations are performed asynchronously, and the
450+ " For the given buffers, discover the project's tests (which includes fetching
451+ " the project structure if it hasn't already been fetched. Finally, fetch the
452+ " buffer code structures. All operations are performed asynchronously, and the
434453" a:Callback is called when all buffer code structures have been fetched.
435454function ! s: utils .initialize (buffers , Callback) abort
436455 call OmniSharp#testrunner#Init (a: buffers )
437- call s: utils .init.await (a: buffers , ' OmniSharp#actions#project#Get ' ,
456+ call s: utils .init.await (a: buffers , ' OmniSharp#testrunner#Discover ' ,
438457 \ funcref (' s:utils.init.await' , [a: buffers , ' OmniSharp#actions#codestructure#Get' ,
439458 \ funcref (' s:utils.init.extract' , [a: Callback ])]))
440459endfunction
@@ -447,7 +466,7 @@ endfunction
447466function ! s: utils .init.extract (Callback, codeStructures) abort
448467 let bufferTests = map (a: codeStructures , {i , cs - > {
449468 \ ' bufnr' : cs [0 ],
450- \ ' tests' : s: utils .extractTests (cs [1 ])
469+ \ ' tests' : s: utils .extractTests (cs [0 ], cs [ 1 ])
451470 \} })
452471 call OmniSharp#testrunner#SetTests (bufferTests)
453472 let dict = { ' f' : a: Callback }
0 commit comments