@@ -20,6 +20,13 @@ public CompletionTests(ITestOutputHelper outputHelper) : base(outputHelper)
2020 {
2121 }
2222
23+ private static int GetNodeBodyLineNumber ( Workspace workspace , string nodeName )
24+ {
25+ var projectContainingNode = workspace . Projects . Single ( p => p . Nodes . Any ( n => n . SourceTitle == nodeName ) ) ;
26+ var node = projectContainingNode . Nodes . Single ( n => n . SourceTitle == nodeName ) ;
27+ return node . BodyStartLine ;
28+ }
29+
2330 [ Fact ]
2431 public async Task Server_OnCompletingStartOfCommand_ReturnsValidCompletions ( )
2532 {
@@ -163,33 +170,104 @@ public async Task Server_OnCompletingPartialJumpCommand_ReturnsNodeNames()
163170 }
164171
165172 [ Fact ]
166- public async Task Server_OnCompletionRequestedInSetStatement_OffersVariableNames ( )
173+ public async Task Server_OnCompletionRequestedInSetStatement_OffersVariableNamesForAssignment ( )
167174 {
168175 // Given
169176 // Given
170177 var ( client , server ) = await Initialize ( ConfigureClient , ConfigureServer ) ;
171178 var filePath = Path . Combine ( TestUtility . PathToTestWorkspace , "Project1" , "Test.yarn" ) ;
172179 var workspace = server . Workspace . GetService < Workspace > ( ) ! ;
173180 var project = workspace . Projects . Single ( p => p . Uri ! . Path . Contains ( "Project1" ) ) ;
181+ var insertionLineNumber = GetNodeBodyLineNumber ( workspace , "CodeCompletionTests" ) ;
174182
175- ChangeTextInDocument ( client , filePath , new Position ( 48 , 0 ) , "<<set " ) ;
183+ ChangeTextInDocument ( client , filePath , new Position ( insertionLineNumber , 0 ) , "<<set " ) ;
176184
177185 // When
178186 var completionResults = await client . RequestCompletion ( new CompletionParams
179187 {
180188 TextDocument = new TextDocumentIdentifier { Uri = filePath } ,
181- Position = new Position ( 48 , "<<set " . Length )
189+ Position = new Position ( insertionLineNumber , "<<set " . Length )
182190 } ) ;
183191
192+ var storedVariables = project . Variables . Where ( v => v . IsInlineExpansion == false ) ;
193+ var smartVariables = project . Variables . Where ( v => v . IsInlineExpansion == true ) ;
194+
195+
184196 // Then
185- completionResults . Should ( ) . NotBeEmpty ( ) ;
186- completionResults . Should ( ) . AllSatisfy ( item =>
197+ storedVariables . Should ( ) . AllSatisfy ( v => completionResults . Should ( ) . Contain ( res => res . Label == v . Name ) ) ;
198+ smartVariables . Should ( ) . AllSatisfy ( v => completionResults . Should ( ) . NotContain ( res => res . Label == v . Name ) ) ;
199+ }
200+
201+
202+ [ Fact ]
203+ public async Task Server_OnCompletionRequestedInSetStatement_OffersIdentifiersForValues ( )
204+ {
205+ // Given
206+ var ( client , server ) = await Initialize ( ConfigureClient , ConfigureServer ) ;
207+ var filePath = Path . Combine ( TestUtility . PathToTestWorkspace , "Project1" , "Test.yarn" ) ;
208+ var workspace = server . Workspace . GetService < Workspace > ( ) ! ;
209+ var project = workspace . Projects . Single ( p => p . Uri ! . Path . Contains ( "Project1" ) ) ;
210+ var insertionLineNumber = GetNodeBodyLineNumber ( workspace , "CodeCompletionTests" ) ;
211+
212+ ChangeTextInDocument ( client , filePath , new Position ( insertionLineNumber , 0 ) , "<<set $x = " ) ;
213+
214+ // When
215+ var completionResults = await client . RequestCompletion ( new CompletionParams
216+ {
217+ TextDocument = new TextDocumentIdentifier { Uri = filePath } ,
218+ Position = new Position ( insertionLineNumber , "<<set $x = " . Length )
219+ } ) ;
220+
221+ var allFunctionsAndVariables = Enumerable . Concat ( project . Variables , project . Functions . Select ( a => a . Declaration ) ) ;
222+ var allEnumCaseNames = project . Enums . SelectMany ( e => e . EnumCases . Select ( c => $ "{ e . Name } .{ c . Key } ") ) ;
223+
224+ allFunctionsAndVariables . Should ( ) . NotBeEmpty ( ) ;
225+ allFunctionsAndVariables . Should ( ) . AllSatisfy ( decl => decl . Should ( ) . NotBeNull ( ) ) ;
226+ allEnumCaseNames . Should ( ) . NotBeEmpty ( ) ;
227+
228+ // Then
229+ // All functions and variables should be in the list of completions
230+ allFunctionsAndVariables . Should ( ) . AllSatisfy ( decl => completionResults . Should ( ) . Contain ( res => res . Label == decl ! . Name ) ) ;
231+ // All enum cases should be in the list of completions
232+ allEnumCaseNames . Should ( ) . AllSatisfy ( caseName => completionResults . Should ( ) . Contain ( res => res . Label == caseName ) ) ;
233+ }
234+
235+ [ InlineData ( [ "<<if " ] ) ]
236+ [ InlineData ( [ "<<elseif " ] ) ]
237+ [ InlineData ( [ "<<myCoolCommand {" ] ) ]
238+ [ Theory ]
239+ public async Task Server_OnCompletionRequestedInStatement_OffersIdentifiers ( string expression )
240+ {
241+ // Given
242+ var ( client , server ) = await Initialize ( ConfigureClient , ConfigureServer ) ;
243+ var filePath = Path . Combine ( TestUtility . PathToTestWorkspace , "Project1" , "Test.yarn" ) ;
244+ var workspace = server . Workspace . GetService < Workspace > ( ) ! ;
245+ var project = workspace . Projects . Single ( p => p . Uri ! . Path . Contains ( "Project1" ) ) ;
246+ var insertionLineNumber = GetNodeBodyLineNumber ( workspace , "CodeCompletionTests" ) ;
247+
248+ ChangeTextInDocument ( client , filePath , new Position ( insertionLineNumber , 0 ) , expression ) ;
249+
250+ // When
251+ var completionResults = await client . RequestCompletion ( new CompletionParams
187252 {
188- var decl = project . Variables . Should ( ) . Contain ( v => v . Name == item . Label , "the completion should be a variable name" ) . Subject ;
189- decl . IsVariable . Should ( ) . BeTrue ( "the declaration should be a variable" ) ;
190- decl . IsInlineExpansion . Should ( ) . BeFalse ( "the variable should be a stored variable" ) ;
191- } , "all completion results should be stored variables" ) ;
253+ TextDocument = new TextDocumentIdentifier { Uri = filePath } ,
254+ Position = new Position ( insertionLineNumber , expression . Length )
255+ } ) ;
256+
257+ // Then
258+ completionResults . Should ( ) . NotBeEmpty ( ) ;
259+
260+ var allFunctionsAndVariables = Enumerable . Concat ( project . Variables , project . Functions . Select ( a => a . Declaration ) ) ;
261+ var allEnumCaseNames = project . Enums . SelectMany ( e => e . EnumCases . Select ( c => $ "{ e . Name } .{ c . Key } ") ) ;
262+
263+ allFunctionsAndVariables . Should ( ) . NotBeEmpty ( ) ;
264+ allFunctionsAndVariables . Should ( ) . AllSatisfy ( decl => decl . Should ( ) . NotBeNull ( ) ) ;
265+ allEnumCaseNames . Should ( ) . NotBeEmpty ( ) ;
266+
267+ // All functions and variables should be in the list of completions
268+ allFunctionsAndVariables . Should ( ) . AllSatisfy ( decl => completionResults . Should ( ) . Contain ( res => res . Label == decl ! . Name ) ) ;
192269
270+ allEnumCaseNames . Should ( ) . AllSatisfy ( caseName => completionResults . Should ( ) . Contain ( res => res . Label == caseName ) ) ;
193271 }
194272
195273 }
0 commit comments