1+ using Microsoft . Extensions . Logging ;
2+ using OmniSharp . Extensions . LanguageServer . Capabilities . Server ;
3+ using OmniSharp . Extensions . LanguageServer . Models ;
4+ using OmniSharp . Extensions . LanguageServerProtocol . Client . Dispatcher ;
5+ using OmniSharp . Extensions . LanguageServerProtocol . Client . Protocol ;
6+ using OmniSharp . Extensions . LanguageServerProtocol . Client . Utilities ;
7+ using System . IO ;
8+ using System . Linq ;
9+ using System . Threading . Tasks ;
10+ using Xunit ;
11+ using Xunit . Abstractions ;
12+
13+ namespace OmniSharp . Extensions . LanguageServerProtocol . Client . Tests
14+ {
15+ /// <summary>
16+ /// Tests for <see cref="LanguageClient"/>.
17+ /// </summary>
18+ public class ClientTests
19+ : PipeServerTestBase
20+ {
21+ /// <summary>
22+ /// Create a new <see cref="LanguageClient"/> test suite.
23+ /// </summary>
24+ /// <param name="testOutput">
25+ /// Output for the current test.
26+ /// </param>
27+ public ClientTests ( ITestOutputHelper testOutput )
28+ : base ( testOutput )
29+ {
30+ }
31+
32+ /// <summary>
33+ /// Get an absolute document path for use in tests.
34+ /// </summary>
35+ string AbsoluteDocumentPath => Path . DirectorySeparatorChar + "Foo.txt" ; // Absolute path, cross-platform compatible.
36+
37+ /// <summary>
38+ /// The <see cref="LanguageClient"/> under test.
39+ /// </summary>
40+ LanguageClient LanguageClient { get ; set ; }
41+
42+ /// <summary>
43+ /// The server-side dispatcher.
44+ /// </summary>
45+ LspDispatcher ServerDispatcher { get ; } = new LspDispatcher ( ) ;
46+
47+ /// <summary>
48+ /// The server-side connection.
49+ /// </summary>
50+ LspConnection ServerConnection { get ; set ; }
51+
52+ /// <summary>
53+ /// Ensure that the language client can successfully request Hover information.
54+ /// </summary>
55+ [ Fact ( DisplayName = "Language client can successfully request hover info" ) ]
56+ public async Task Hover_Success ( )
57+ {
58+ await Connect ( ) ;
59+
60+ const int line = 5 ;
61+ const int column = 5 ;
62+ var expectedHoverContent = new MarkedStringContainer ( "123" , "456" , "789" ) ;
63+
64+ ServerDispatcher . HandleRequest < TextDocumentPositionParams , Hover > ( "textDocument/hover" , ( request , cancellationToken ) =>
65+ {
66+ Assert . NotNull ( request . TextDocument ) ;
67+
68+ Assert . Equal ( AbsoluteDocumentPath ,
69+ DocumentUri . GetFileSystemPath ( request . TextDocument . Uri )
70+ ) ;
71+
72+ Assert . Equal ( line , request . Position . Line ) ;
73+ Assert . Equal ( column , request . Position . Character ) ;
74+
75+ return Task . FromResult ( new Hover
76+ {
77+ Contents = expectedHoverContent ,
78+ Range = new Range
79+ {
80+ Start = request . Position ,
81+ End = request . Position
82+ }
83+ } ) ;
84+ } ) ;
85+
86+ Hover hover = await LanguageClient . TextDocument . Hover ( AbsoluteDocumentPath , line , column ) ;
87+
88+ Assert . NotNull ( hover . Range ) ;
89+ Assert . NotNull ( hover . Range . Start ) ;
90+ Assert . NotNull ( hover . Range . End ) ;
91+
92+ Assert . Equal ( line , hover . Range . Start . Line ) ;
93+ Assert . Equal ( column , hover . Range . Start . Character ) ;
94+
95+ Assert . Equal ( line , hover . Range . End . Line ) ;
96+ Assert . Equal ( column , hover . Range . End . Character ) ;
97+
98+ Assert . NotNull ( hover . Contents ) ;
99+ Assert . Equal ( expectedHoverContent . Select ( markedString => markedString . Value ) ,
100+ hover . Contents . Select (
101+ markedString => markedString . Value
102+ )
103+ ) ;
104+ }
105+
106+ /// <summary>
107+ /// Connect the client and server.
108+ /// </summary>
109+ /// <param name="handleServerInitialize">
110+ /// Add standard handlers for server initialisation?
111+ /// </param>
112+ async Task Connect ( bool handleServerInitialize = true )
113+ {
114+ ServerConnection = await CreateServerConnection ( ) ;
115+ ServerConnection . Connect ( ServerDispatcher ) ;
116+
117+ if ( handleServerInitialize )
118+ HandleServerInitialize ( ) ;
119+
120+ LanguageClient = await CreateClient ( initialize : true ) ;
121+ }
122+
123+ /// <summary>
124+ /// Add standard handlers for sever initialisation.
125+ /// </summary>
126+ void HandleServerInitialize ( )
127+ {
128+ ServerDispatcher . HandleRequest < InitializeParams , InitializeResult > ( "initialize" , ( request , cancellationToken ) =>
129+ {
130+ return Task . FromResult ( new InitializeResult
131+ {
132+ Capabilities = new ServerCapabilities
133+ {
134+ HoverProvider = true
135+ }
136+ } ) ;
137+ } ) ;
138+ ServerDispatcher . HandleEmptyNotification ( "initialized" , ( ) =>
139+ {
140+ Log . LogInformation ( "Server initialized." ) ;
141+ } ) ;
142+ }
143+ }
144+ }
0 commit comments