diff --git a/test/PowerShellEditorServices.Test.Shared/Definition/FindsDotSourcedFile.cs b/test/PowerShellEditorServices.Test.Shared/Definition/FindsDotSourcedFile.cs index c18de32a3..e69976d2c 100644 --- a/test/PowerShellEditorServices.Test.Shared/Definition/FindsDotSourcedFile.cs +++ b/test/PowerShellEditorServices.Test.Shared/Definition/FindsDotSourcedFile.cs @@ -5,17 +5,16 @@ namespace Microsoft.PowerShell.EditorServices.Test.Shared.Definition { - public class FindsDotSourcedFile + public static class FindsDotSourcedFileData { - public static readonly ScriptRegion SourceDetails = - new ScriptRegion( - file: TestUtilities.NormalizePath("References/DotSources.ps1"), - text: string.Empty, - startLineNumber: 1, - startColumnNumber: 3, - startOffset: 0, - endLineNumber: 0, - endColumnNumber: 0, - endOffset: 0); + public static readonly ScriptRegion SourceDetails = new( + file: TestUtilities.NormalizePath("References/DotSources.ps1"), + text: string.Empty, + startLineNumber: 1, + startColumnNumber: 3, + startOffset: 0, + endLineNumber: 0, + endColumnNumber: 0, + endOffset: 0); } } diff --git a/test/PowerShellEditorServices.Test.Shared/Definition/FindsFunctionDefinition.cs b/test/PowerShellEditorServices.Test.Shared/Definition/FindsFunctionDefinition.cs index f75db35d4..db3465096 100644 --- a/test/PowerShellEditorServices.Test.Shared/Definition/FindsFunctionDefinition.cs +++ b/test/PowerShellEditorServices.Test.Shared/Definition/FindsFunctionDefinition.cs @@ -5,17 +5,16 @@ namespace Microsoft.PowerShell.EditorServices.Test.Shared.Definition { - public class FindsFunctionDefinition + public static class FindsFunctionDefinitionData { - public static readonly ScriptRegion SourceDetails = - new ScriptRegion( - file: TestUtilities.NormalizePath("References/SimpleFile.ps1"), - text: string.Empty, - startLineNumber: 3, - startColumnNumber: 12, - startOffset: 0, - endLineNumber: 0, - endColumnNumber: 0, - endOffset: 0); + public static readonly ScriptRegion SourceDetails = new( + file: TestUtilities.NormalizePath("References/SimpleFile.ps1"), + text: string.Empty, + startLineNumber: 3, + startColumnNumber: 12, + startOffset: 0, + endLineNumber: 0, + endColumnNumber: 0, + endOffset: 0); } } diff --git a/test/PowerShellEditorServices.Test.Shared/Definition/FindsFunctionDefinitionInDotSourceReference.cs b/test/PowerShellEditorServices.Test.Shared/Definition/FindsFunctionDefinitionInDotSourceReference.cs index ac79688f0..b7456faeb 100644 --- a/test/PowerShellEditorServices.Test.Shared/Definition/FindsFunctionDefinitionInDotSourceReference.cs +++ b/test/PowerShellEditorServices.Test.Shared/Definition/FindsFunctionDefinitionInDotSourceReference.cs @@ -5,17 +5,16 @@ namespace Microsoft.PowerShell.EditorServices.Test.Shared.Definition { - public class FindsFunctionDefinitionInDotSourceReference + public static class FindsFunctionDefinitionInDotSourceReferenceData { - public static readonly ScriptRegion SourceDetails = - new ScriptRegion( - file: TestUtilities.NormalizePath("References/FileWithReferences.ps1"), - text: string.Empty, - startLineNumber: 3, - startColumnNumber: 6, - startOffset: 0, - endLineNumber: 0, - endColumnNumber: 0, - endOffset: 0); + public static readonly ScriptRegion SourceDetails = new( + file: TestUtilities.NormalizePath("References/FileWithReferences.ps1"), + text: string.Empty, + startLineNumber: 3, + startColumnNumber: 6, + startOffset: 0, + endLineNumber: 0, + endColumnNumber: 0, + endOffset: 0); } } diff --git a/test/PowerShellEditorServices.Test.Shared/Definition/FindsFunctionDefinitionInWorkspace.cs b/test/PowerShellEditorServices.Test.Shared/Definition/FindsFunctionDefinitionInWorkspace.cs index 184e4143d..a88c143bf 100644 --- a/test/PowerShellEditorServices.Test.Shared/Definition/FindsFunctionDefinitionInWorkspace.cs +++ b/test/PowerShellEditorServices.Test.Shared/Definition/FindsFunctionDefinitionInWorkspace.cs @@ -5,17 +5,16 @@ namespace Microsoft.PowerShell.EditorServices.Test.Shared.Definition { - public class FindsFunctionDefinitionInWorkspace + public static class FindsFunctionDefinitionInWorkspaceData { - public static readonly ScriptRegion SourceDetails = - new ScriptRegion( - file: TestUtilities.NormalizePath("References/ReferenceFileD.ps1"), - text: string.Empty, - startLineNumber: 1, - startColumnNumber: 2, - startOffset: 0, - endLineNumber: 0, - endColumnNumber: 0, - endOffset: 0); + public static readonly ScriptRegion SourceDetails = new( + file: TestUtilities.NormalizePath("References/ReferenceFileD.ps1"), + text: string.Empty, + startLineNumber: 1, + startColumnNumber: 2, + startOffset: 0, + endLineNumber: 0, + endColumnNumber: 0, + endOffset: 0); } } diff --git a/test/PowerShellEditorServices.Test.Shared/Definition/FindsVariableDefinition.cs b/test/PowerShellEditorServices.Test.Shared/Definition/FindsVariableDefinition.cs index 0013ec95f..e70fa98c8 100644 --- a/test/PowerShellEditorServices.Test.Shared/Definition/FindsVariableDefinition.cs +++ b/test/PowerShellEditorServices.Test.Shared/Definition/FindsVariableDefinition.cs @@ -5,17 +5,16 @@ namespace Microsoft.PowerShell.EditorServices.Test.Shared.Definition { - public class FindsVariableDefinition + public static class FindsVariableDefinitionData { - public static readonly ScriptRegion SourceDetails = - new ScriptRegion( - file: TestUtilities.NormalizePath("References/SimpleFile.ps1"), - text: string.Empty, - startLineNumber: 8, - startColumnNumber: 3, - startOffset: 0, - endLineNumber: 0, - endColumnNumber: 0, - endOffset: 0); + public static readonly ScriptRegion SourceDetails = new( + file: TestUtilities.NormalizePath("References/SimpleFile.ps1"), + text: string.Empty, + startLineNumber: 8, + startColumnNumber: 3, + startOffset: 0, + endLineNumber: 0, + endColumnNumber: 0, + endOffset: 0); } } diff --git a/test/PowerShellEditorServices.Test.Shared/Occurrences/FindOccurrencesOnParameter.cs b/test/PowerShellEditorServices.Test.Shared/Occurrences/FindOccurrencesOnParameter.cs index 25eb2551b..5b708a07d 100644 --- a/test/PowerShellEditorServices.Test.Shared/Occurrences/FindOccurrencesOnParameter.cs +++ b/test/PowerShellEditorServices.Test.Shared/Occurrences/FindOccurrencesOnParameter.cs @@ -5,17 +5,16 @@ namespace Microsoft.PowerShell.EditorServices.Test.Shared.Occurrences { - public class FindOccurrencesOnParameter + public static class FindOccurrencesOnParameterData { - public static readonly ScriptRegion SourceDetails = - new ScriptRegion( - file: TestUtilities.NormalizePath("References/SimpleFile.ps1"), - text: string.Empty, - startLineNumber: 1, - startColumnNumber: 31, - startOffset: 0, - endLineNumber: 0, - endColumnNumber: 0, - endOffset: 0); + public static readonly ScriptRegion SourceDetails = new( + file: TestUtilities.NormalizePath("References/SimpleFile.ps1"), + text: string.Empty, + startLineNumber: 1, + startColumnNumber: 31, + startOffset: 0, + endLineNumber: 0, + endColumnNumber: 0, + endOffset: 0); } } diff --git a/test/PowerShellEditorServices.Test.Shared/Occurrences/FindsOccurrencesOnFunction.cs b/test/PowerShellEditorServices.Test.Shared/Occurrences/FindsOccurrencesOnFunction.cs index 4b084d500..53f47677b 100644 --- a/test/PowerShellEditorServices.Test.Shared/Occurrences/FindsOccurrencesOnFunction.cs +++ b/test/PowerShellEditorServices.Test.Shared/Occurrences/FindsOccurrencesOnFunction.cs @@ -5,17 +5,16 @@ namespace Microsoft.PowerShell.EditorServices.Test.Shared.Occurrences { - public class FindsOccurrencesOnFunction + public static class FindsOccurrencesOnFunctionData { - public static readonly ScriptRegion SourceDetails = - new ScriptRegion( - file: TestUtilities.NormalizePath("References/SimpleFile.ps1"), - text: string.Empty, - startLineNumber: 1, - startColumnNumber: 17, - startOffset: 0, - endLineNumber: 0, - endColumnNumber: 0, - endOffset: 0); + public static readonly ScriptRegion SourceDetails = new( + file: TestUtilities.NormalizePath("References/SimpleFile.ps1"), + text: string.Empty, + startLineNumber: 1, + startColumnNumber: 17, + startOffset: 0, + endLineNumber: 0, + endColumnNumber: 0, + endOffset: 0); } } diff --git a/test/PowerShellEditorServices.Test.Shared/ParameterHints/FindsParameterSetsOnCommand.cs b/test/PowerShellEditorServices.Test.Shared/ParameterHints/FindsParameterSetsOnCommand.cs index 8a141d2e0..f2ff41331 100644 --- a/test/PowerShellEditorServices.Test.Shared/ParameterHints/FindsParameterSetsOnCommand.cs +++ b/test/PowerShellEditorServices.Test.Shared/ParameterHints/FindsParameterSetsOnCommand.cs @@ -5,17 +5,16 @@ namespace Microsoft.PowerShell.EditorServices.Test.Shared.ParameterHint { - public class FindsParameterSetsOnCommand + public static class FindsParameterSetsOnCommandData { - public static readonly ScriptRegion SourceDetails = - new ScriptRegion( - file: TestUtilities.NormalizePath("ParameterHints/ParamHints.ps1"), - text: string.Empty, - startLineNumber: 1, - startColumnNumber: 14, - startOffset: 0, - endLineNumber: 0, - endColumnNumber: 0, - endOffset: 0); + public static readonly ScriptRegion SourceDetails = new( + file: TestUtilities.NormalizePath("ParameterHints/ParamHints.ps1"), + text: string.Empty, + startLineNumber: 1, + startColumnNumber: 14, + startOffset: 0, + endLineNumber: 0, + endColumnNumber: 0, + endOffset: 0); } } diff --git a/test/PowerShellEditorServices.Test.Shared/ParameterHints/FindsParameterSetsOnCommandWithSpaces.cs b/test/PowerShellEditorServices.Test.Shared/ParameterHints/FindsParameterSetsOnCommandWithSpaces.cs index 4dda4a847..a63ebc470 100644 --- a/test/PowerShellEditorServices.Test.Shared/ParameterHints/FindsParameterSetsOnCommandWithSpaces.cs +++ b/test/PowerShellEditorServices.Test.Shared/ParameterHints/FindsParameterSetsOnCommandWithSpaces.cs @@ -5,17 +5,16 @@ namespace Microsoft.PowerShell.EditorServices.Test.Shared.ParameterHint { - public class FindsParameterSetsOnCommandWithSpaces + public static class FindsParameterSetsOnCommandWithSpacesData { - public static readonly ScriptRegion SourceDetails = - new ScriptRegion( - file: TestUtilities.NormalizePath("ParameterHints/ParamHints.ps1"), - text: string.Empty, - startLineNumber: 9, - startColumnNumber: 31, - startOffset: 0, - endLineNumber: 0, - endColumnNumber: 0, - endOffset: 0); + public static readonly ScriptRegion SourceDetails = new( + file: TestUtilities.NormalizePath("ParameterHints/ParamHints.ps1"), + text: string.Empty, + startLineNumber: 9, + startColumnNumber: 31, + startOffset: 0, + endLineNumber: 0, + endColumnNumber: 0, + endOffset: 0); } } diff --git a/test/PowerShellEditorServices.Test.Shared/References/FindsReferencesOnBuiltInCommandWithAlias.cs b/test/PowerShellEditorServices.Test.Shared/References/FindsReferencesOnBuiltInCommandWithAlias.cs index 934c8bf61..1bc7ec8e6 100644 --- a/test/PowerShellEditorServices.Test.Shared/References/FindsReferencesOnBuiltInCommandWithAlias.cs +++ b/test/PowerShellEditorServices.Test.Shared/References/FindsReferencesOnBuiltInCommandWithAlias.cs @@ -5,31 +5,28 @@ namespace Microsoft.PowerShell.EditorServices.Test.Shared.References { - public class FindsReferencesOnBuiltInCommandWithAlias + public static class FindsReferencesOnBuiltInCommandWithAliasData { - public static readonly ScriptRegion SourceDetails = - new ScriptRegion( - file: TestUtilities.NormalizePath("References/SimpleFile.ps1"), - text: string.Empty, - startLineNumber: 14, - startColumnNumber: 3, - startOffset: 0, - endLineNumber: 0, - endColumnNumber: 0, - endOffset: 0); + public static readonly ScriptRegion SourceDetails = new( + file: TestUtilities.NormalizePath("References/SimpleFile.ps1"), + text: string.Empty, + startLineNumber: 14, + startColumnNumber: 3, + startOffset: 0, + endLineNumber: 0, + endColumnNumber: 0, + endOffset: 0); } - public class FindsReferencesOnBuiltInAlias + public static class FindsReferencesOnBuiltInAliasData { - public static readonly ScriptRegion SourceDetails = - new ScriptRegion( - file: TestUtilities.NormalizePath("References/SimpleFile.ps1"), - text: string.Empty, - startLineNumber: 15, - startColumnNumber: 2, - startOffset: 0, - endLineNumber: 0, - endColumnNumber: 0, - endOffset: 0); + public static readonly ScriptRegion SourceDetails = new( + file: TestUtilities.NormalizePath("References/SimpleFile.ps1"), + text: string.Empty, + startLineNumber: 15, + startColumnNumber: 2, + startOffset: 0, + endLineNumber: 0, + endColumnNumber: 0, + endOffset: 0); } } - diff --git a/test/PowerShellEditorServices.Test.Shared/References/FindsReferencesOnFunction.cs b/test/PowerShellEditorServices.Test.Shared/References/FindsReferencesOnFunction.cs index dd2f271b9..d7a8df301 100644 --- a/test/PowerShellEditorServices.Test.Shared/References/FindsReferencesOnFunction.cs +++ b/test/PowerShellEditorServices.Test.Shared/References/FindsReferencesOnFunction.cs @@ -5,18 +5,16 @@ namespace Microsoft.PowerShell.EditorServices.Test.Shared.References { - public class FindsReferencesOnFunction + public static class FindsReferencesOnFunctionData { - public static readonly ScriptRegion SourceDetails = - new ScriptRegion( - file: TestUtilities.NormalizePath("References/SimpleFile.ps1"), - text: string.Empty, - startLineNumber: 3, - startColumnNumber: 8, - startOffset: 0, - endLineNumber: 0, - endColumnNumber: 0, - endOffset: 0); + public static readonly ScriptRegion SourceDetails = new( + file: TestUtilities.NormalizePath("References/SimpleFile.ps1"), + text: string.Empty, + startLineNumber: 3, + startColumnNumber: 8, + startOffset: 0, + endLineNumber: 0, + endColumnNumber: 0, + endOffset: 0); } } - diff --git a/test/PowerShellEditorServices.Test.Shared/References/FindsReferencesOnFunctionMultiFileDotSource.cs b/test/PowerShellEditorServices.Test.Shared/References/FindsReferencesOnFunctionMultiFileDotSource.cs index 56ba34ff8..6a231ae60 100644 --- a/test/PowerShellEditorServices.Test.Shared/References/FindsReferencesOnFunctionMultiFileDotSource.cs +++ b/test/PowerShellEditorServices.Test.Shared/References/FindsReferencesOnFunctionMultiFileDotSource.cs @@ -5,31 +5,29 @@ namespace Microsoft.PowerShell.EditorServices.Test.Shared.References { - public class FindsReferencesOnFunctionMultiFileDotSourceFileB + public static class FindsReferencesOnFunctionMultiFileDotSourceFileB { - public static readonly ScriptRegion SourceDetails = - new ScriptRegion( - file: TestUtilities.NormalizePath("References/ReferenceFileB.ps1"), - text: string.Empty, - startLineNumber: 5, - startColumnNumber: 8, - startOffset: 0, - endLineNumber: 0, - endColumnNumber: 0, - endOffset: 0); + public static readonly ScriptRegion SourceDetails = new( + file: TestUtilities.NormalizePath("References/ReferenceFileB.ps1"), + text: string.Empty, + startLineNumber: 5, + startColumnNumber: 8, + startOffset: 0, + endLineNumber: 0, + endColumnNumber: 0, + endOffset: 0); } - public class FindsReferencesOnFunctionMultiFileDotSourceFileC + + public static class FindsReferencesOnFunctionMultiFileDotSourceFileC { - public static readonly ScriptRegion SourceDetails = - new ScriptRegion( - file: TestUtilities.NormalizePath("References/ReferenceFileC.ps1"), - text: string.Empty, - startLineNumber: 4, - startColumnNumber: 10, - startOffset: 0, - endLineNumber: 0, - endColumnNumber: 0, - endOffset: 0); + public static readonly ScriptRegion SourceDetails = new( + file: TestUtilities.NormalizePath("References/ReferenceFileC.ps1"), + text: string.Empty, + startLineNumber: 4, + startColumnNumber: 10, + startOffset: 0, + endLineNumber: 0, + endColumnNumber: 0, + endOffset: 0); } } - diff --git a/test/PowerShellEditorServices.Test.Shared/References/FindsReferencesonVariable.cs b/test/PowerShellEditorServices.Test.Shared/References/FindsReferencesonVariable.cs index 515452f03..90c58654e 100644 --- a/test/PowerShellEditorServices.Test.Shared/References/FindsReferencesonVariable.cs +++ b/test/PowerShellEditorServices.Test.Shared/References/FindsReferencesonVariable.cs @@ -5,17 +5,16 @@ namespace Microsoft.PowerShell.EditorServices.Test.Shared.References { - public class FindsReferencesOnVariable + public static class FindsReferencesOnVariableData { - public static readonly ScriptRegion SourceDetails = - new ScriptRegion( - file: TestUtilities.NormalizePath("References/SimpleFile.ps1"), - text: string.Empty, - startLineNumber: 10, - startColumnNumber: 17, - startOffset: 0, - endLineNumber: 0, - endColumnNumber: 0, - endOffset: 0); + public static readonly ScriptRegion SourceDetails = new( + file: TestUtilities.NormalizePath("References/SimpleFile.ps1"), + text: string.Empty, + startLineNumber: 10, + startColumnNumber: 17, + startOffset: 0, + endLineNumber: 0, + endColumnNumber: 0, + endOffset: 0); } } diff --git a/test/PowerShellEditorServices.Test.Shared/SymbolDetails/FindsDetailsForBuiltInCommand.cs b/test/PowerShellEditorServices.Test.Shared/SymbolDetails/FindsDetailsForBuiltInCommand.cs index 71b1ffa02..e0818c166 100644 --- a/test/PowerShellEditorServices.Test.Shared/SymbolDetails/FindsDetailsForBuiltInCommand.cs +++ b/test/PowerShellEditorServices.Test.Shared/SymbolDetails/FindsDetailsForBuiltInCommand.cs @@ -5,17 +5,16 @@ namespace Microsoft.PowerShell.EditorServices.Test.Shared.SymbolDetails { - public class FindsDetailsForBuiltInCommand + public static class FindsDetailsForBuiltInCommandData { - public static readonly ScriptRegion SourceDetails = - new ScriptRegion( - file: TestUtilities.NormalizePath("SymbolDetails/SymbolDetails.ps1"), - text: string.Empty, - startLineNumber: 1, - startColumnNumber: 10, - startOffset: 0, - endLineNumber: 0, - endColumnNumber: 0, - endOffset: 0); + public static readonly ScriptRegion SourceDetails = new( + file: TestUtilities.NormalizePath("SymbolDetails/SymbolDetails.ps1"), + text: string.Empty, + startLineNumber: 1, + startColumnNumber: 10, + startOffset: 0, + endLineNumber: 0, + endColumnNumber: 0, + endOffset: 0); } } diff --git a/test/PowerShellEditorServices.Test/Language/CompletionHandlerTests.cs b/test/PowerShellEditorServices.Test/Language/CompletionHandlerTests.cs new file mode 100644 index 000000000..b83689cb3 --- /dev/null +++ b/test/PowerShellEditorServices.Test/Language/CompletionHandlerTests.cs @@ -0,0 +1,160 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging.Abstractions; +using Microsoft.PowerShell.EditorServices.Handlers; +using Microsoft.PowerShell.EditorServices.Services; +using Microsoft.PowerShell.EditorServices.Services.PowerShell.Host; +using Microsoft.PowerShell.EditorServices.Services.TextDocument; +using Microsoft.PowerShell.EditorServices.Test.Shared; +using Microsoft.PowerShell.EditorServices.Test.Shared.Completion; +using Microsoft.PowerShell.EditorServices.Utility; +using Xunit; + +namespace Microsoft.PowerShell.EditorServices.Test.Language +{ + [Trait("Category", "Completions")] + public class CompletionHandlerTests : IDisposable + { + private readonly PsesInternalHost psesHost; + private readonly WorkspaceService workspace; + private readonly PsesCompletionHandler completionHandler; + + public CompletionHandlerTests() + { + psesHost = PsesHostFactory.Create(NullLoggerFactory.Instance); + workspace = new WorkspaceService(NullLoggerFactory.Instance); + completionHandler = new PsesCompletionHandler(NullLoggerFactory.Instance, psesHost, psesHost, workspace); + } + + public void Dispose() + { + psesHost.StopAsync().GetAwaiter().GetResult(); + GC.SuppressFinalize(this); + } + + private ScriptFile GetScriptFile(ScriptRegion scriptRegion) => workspace.GetFile(TestUtilities.GetSharedPath(scriptRegion.File)); + + private async Task GetCompletionResults(ScriptRegion scriptRegion) + { + return await completionHandler.GetCompletionsInFileAsync( + GetScriptFile(scriptRegion), + scriptRegion.StartLineNumber, + scriptRegion.StartColumnNumber).ConfigureAwait(true); + } + + [Fact] + public async Task CompletesCommandInFile() + { + CompletionResults completionResults = await GetCompletionResults(CompleteCommandInFile.SourceDetails).ConfigureAwait(true); + Assert.NotEmpty(completionResults.Completions); + Assert.Equal(CompleteCommandInFile.ExpectedCompletion, completionResults.Completions[0]); + } + + [Fact] + public async Task CompletesCommandFromModule() + { + CompletionResults completionResults = await GetCompletionResults(CompleteCommandFromModule.SourceDetails).ConfigureAwait(true); + + Assert.NotEmpty(completionResults.Completions); + + Assert.Equal( + CompleteCommandFromModule.ExpectedCompletion.CompletionText, + completionResults.Completions[0].CompletionText); + + Assert.Equal( + CompleteCommandFromModule.ExpectedCompletion.CompletionType, + completionResults.Completions[0].CompletionType); + + Assert.NotNull(completionResults.Completions[0].ToolTipText); + } + + [SkippableFact] + public async Task CompletesTypeName() + { + Skip.If( + !VersionUtils.IsNetCore, + "In Windows PowerShell the CommandCompletion fails in the test harness, but works manually."); + + CompletionResults completionResults = await GetCompletionResults(CompleteTypeName.SourceDetails).ConfigureAwait(true); + + Assert.NotEmpty(completionResults.Completions); + + Assert.Equal( + CompleteTypeName.ExpectedCompletion.CompletionText, + completionResults.Completions[0].CompletionText); + + Assert.Equal( + CompleteTypeName.ExpectedCompletion.CompletionType, + completionResults.Completions[0].CompletionType); + + Assert.NotNull(completionResults.Completions[0].ToolTipText); + } + + [Trait("Category", "Completions")] + [SkippableFact] + public async Task CompletesNamespace() + { + Skip.If( + !VersionUtils.IsNetCore, + "In Windows PowerShell the CommandCompletion fails in the test harness, but works manually."); + + CompletionResults completionResults = await GetCompletionResults(CompleteNamespace.SourceDetails).ConfigureAwait(true); + + Assert.NotEmpty(completionResults.Completions); + + Assert.Equal( + CompleteNamespace.ExpectedCompletion.CompletionText, + completionResults.Completions[0].CompletionText); + + Assert.Equal( + CompleteNamespace.ExpectedCompletion.CompletionType, + completionResults.Completions[0].CompletionType); + + Assert.NotNull(completionResults.Completions[0].ToolTipText); + } + + [Fact] + public async Task CompletesVariableInFile() + { + CompletionResults completionResults = await GetCompletionResults(CompleteVariableInFile.SourceDetails).ConfigureAwait(true); + + Assert.Single(completionResults.Completions); + + Assert.Equal( + CompleteVariableInFile.ExpectedCompletion, + completionResults.Completions[0]); + } + + [Fact] + public async Task CompletesAttributeValue() + { + CompletionResults completionResults = await GetCompletionResults(CompleteAttributeValue.SourceDetails).ConfigureAwait(true); + + Assert.NotEmpty(completionResults.Completions); + + Assert.Equal( + CompleteAttributeValue.ExpectedRange, + completionResults.ReplacedRange); + } + + [Fact] + public async Task CompletesFilePath() + { + CompletionResults completionResults = await GetCompletionResults(CompleteFilePath.SourceDetails).ConfigureAwait(true); + + Assert.NotEmpty(completionResults.Completions); + + // TODO: Since this is a path completion, this test will need to be + // platform specific. Probably something like: + // - Windows: C:\Program + // - macOS: /User + // - Linux: /hom + //Assert.Equal( + // CompleteFilePath.ExpectedRange, + // completionResults.ReplacedRange); + } + } +} diff --git a/test/PowerShellEditorServices.Test/Language/LanguageServiceTests.cs b/test/PowerShellEditorServices.Test/Language/LanguageServiceTests.cs deleted file mode 100644 index 68a6db95a..000000000 --- a/test/PowerShellEditorServices.Test/Language/LanguageServiceTests.cs +++ /dev/null @@ -1,528 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Runtime.InteropServices; -using System.Threading.Tasks; -using Microsoft.Extensions.Logging.Abstractions; -using Microsoft.PowerShell.EditorServices.Handlers; -using Microsoft.PowerShell.EditorServices.Services; -using Microsoft.PowerShell.EditorServices.Services.PowerShell.Host; -using Microsoft.PowerShell.EditorServices.Services.Symbols; -using Microsoft.PowerShell.EditorServices.Services.TextDocument; -using Microsoft.PowerShell.EditorServices.Test.Shared; -using Microsoft.PowerShell.EditorServices.Test.Shared.Completion; -using Microsoft.PowerShell.EditorServices.Test.Shared.Definition; -using Microsoft.PowerShell.EditorServices.Test.Shared.Occurrences; -using Microsoft.PowerShell.EditorServices.Test.Shared.ParameterHint; -using Microsoft.PowerShell.EditorServices.Test.Shared.References; -using Microsoft.PowerShell.EditorServices.Test.Shared.SymbolDetails; -using Microsoft.PowerShell.EditorServices.Test.Shared.Symbols; -using Microsoft.PowerShell.EditorServices.Utility; -using Xunit; -using Xunit.Abstractions; - -namespace Microsoft.PowerShell.EditorServices.Test.Language -{ - public class LanguageServiceTests : IDisposable - { - private readonly WorkspaceService workspace; - private readonly SymbolsService symbolsService; - private readonly PsesCompletionHandler completionHandler; - private readonly PsesInternalHost _psesHost; - private static readonly string s_baseSharedScriptPath = - Path.Combine( - Path.GetDirectoryName(VersionUtils.IsWindows - // On non-Windows platforms, CodeBase has file:// in it. - // On Windows, Location points to a temp directory. - ? typeof(LanguageServiceTests).Assembly.CodeBase - : typeof(LanguageServiceTests).Assembly.Location), - "..","..","..","..", - "PowerShellEditorServices.Test.Shared"); - - public LanguageServiceTests() - { - _psesHost = PsesHostFactory.Create(NullLoggerFactory.Instance); - - workspace = new WorkspaceService(NullLoggerFactory.Instance); - symbolsService = new SymbolsService(NullLoggerFactory.Instance, _psesHost, _psesHost, workspace, new ConfigurationService()); - completionHandler = new PsesCompletionHandler(NullLoggerFactory.Instance, _psesHost, _psesHost, workspace); - } - - public void Dispose() - { - _psesHost.StopAsync().GetAwaiter().GetResult(); - } - - [Trait("Category", "Completions")] - [Fact] - public async Task LanguageServiceCompletesCommandInFile() - { - CompletionResults completionResults = - await this.GetCompletionResults( - CompleteCommandInFile.SourceDetails).ConfigureAwait(false); - - Assert.NotEmpty(completionResults.Completions); - Assert.Equal( - CompleteCommandInFile.ExpectedCompletion, - completionResults.Completions[0]); - } - - [Trait("Category", "Completions")] - [Fact] - public async Task LanguageServiceCompletesCommandFromModule() - { - CompletionResults completionResults = - await this.GetCompletionResults( - CompleteCommandFromModule.SourceDetails).ConfigureAwait(false); - - Assert.NotEmpty(completionResults.Completions); - - Assert.Equal( - CompleteCommandFromModule.ExpectedCompletion.CompletionText, - completionResults.Completions[0].CompletionText - ); - - Assert.Equal( - CompleteCommandFromModule.ExpectedCompletion.CompletionType, - completionResults.Completions[0].CompletionType - ); - - Assert.NotNull(completionResults.Completions[0].ToolTipText); - } - - [Trait("Category", "Completions")] - [SkippableFact] - public async Task LanguageServiceCompletesTypeName() - { - Skip.If( - !VersionUtils.IsNetCore, - "Windows PowerShell return no results from CommandCompletion in the test harness. Since it works in PS7 and works manually when I run the extension, I'm skipping this test"); - - CompletionResults completionResults = - await this.GetCompletionResults( - CompleteTypeName.SourceDetails).ConfigureAwait(false); - - Assert.NotEmpty(completionResults.Completions); - - Assert.Equal( - CompleteTypeName.ExpectedCompletion.CompletionText, - completionResults.Completions[0].CompletionText - ); - - Assert.Equal( - CompleteTypeName.ExpectedCompletion.CompletionType, - completionResults.Completions[0].CompletionType - ); - - Assert.NotNull(completionResults.Completions[0].ToolTipText); - } - - [Trait("Category", "Completions")] - [SkippableFact] - public async Task LanguageServiceCompletesNamespace() - { - Skip.If( - !VersionUtils.IsNetCore, - "Windows PowerShell return no results from CommandCompletion in the test harness. Since it works in PS7 and works manually when I run the extension, I'm skipping this test"); - - CompletionResults completionResults = - await this.GetCompletionResults( - CompleteNamespace.SourceDetails).ConfigureAwait(false); - - Assert.NotEmpty(completionResults.Completions); - - Assert.Equal( - CompleteNamespace.ExpectedCompletion.CompletionText, - completionResults.Completions[0].CompletionText - ); - - Assert.Equal( - CompleteNamespace.ExpectedCompletion.CompletionType, - completionResults.Completions[0].CompletionType - ); - - Assert.NotNull(completionResults.Completions[0].ToolTipText); - } - - [Trait("Category", "Completions")] - [Fact] - public async Task LanguageServiceCompletesVariableInFile() - { - CompletionResults completionResults = - await this.GetCompletionResults( - CompleteVariableInFile.SourceDetails).ConfigureAwait(false); - - Assert.Single(completionResults.Completions); - Assert.Equal( - CompleteVariableInFile.ExpectedCompletion, - completionResults.Completions[0]); - } - - [Trait("Category", "Completions")] - [Fact] - public async Task LanguageServiceCompletesAttributeValue() - { - CompletionResults completionResults = - await this.GetCompletionResults( - CompleteAttributeValue.SourceDetails).ConfigureAwait(false); - - Assert.NotEmpty(completionResults.Completions); - Assert.Equal( - CompleteAttributeValue.ExpectedRange, - completionResults.ReplacedRange); - } - - [Trait("Category", "Completions")] - [Fact] - public async Task LanguageServiceCompletesFilePath() - { - CompletionResults completionResults = - await this.GetCompletionResults( - CompleteFilePath.SourceDetails).ConfigureAwait(false); - - Assert.NotEmpty(completionResults.Completions); - // TODO: Since this is a path completion, this test will need to be - // platform specific. Probably something like: - // - Windows: C:\Program - // - macOS: /User - // - Linux: /hom - //Assert.Equal( - // CompleteFilePath.ExpectedRange, - // completionResults.ReplacedRange); - } - - [Trait("Category", "Symbols")] - [Fact] - public async Task LanguageServiceFindsParameterHintsOnCommand() - { - ParameterSetSignatures paramSignatures = - await this.GetParamSetSignatures( - FindsParameterSetsOnCommand.SourceDetails).ConfigureAwait(false); - - Assert.NotNull(paramSignatures); - Assert.Equal("Get-Process", paramSignatures.CommandName); - Assert.Equal(6, paramSignatures.Signatures.Count()); - } - - [Trait("Category", "Symbols")] - [Fact] - public async Task LanguageServiceFindsCommandForParamHintsWithSpaces() - { - ParameterSetSignatures paramSignatures = - await this.GetParamSetSignatures( - FindsParameterSetsOnCommandWithSpaces.SourceDetails).ConfigureAwait(false); - - Assert.NotNull(paramSignatures); - Assert.Equal("Write-Host", paramSignatures.CommandName); - Assert.Single(paramSignatures.Signatures); - } - - [Trait("Category", "Symbols")] - [Fact] - public async Task LanguageServiceFindsFunctionDefinition() - { - SymbolReference definitionResult = - await this.GetDefinition( - FindsFunctionDefinition.SourceDetails).ConfigureAwait(false); - - Assert.Equal(1, definitionResult.ScriptRegion.StartLineNumber); - Assert.Equal(10, definitionResult.ScriptRegion.StartColumnNumber); - Assert.Equal("My-Function", definitionResult.SymbolName); - } - - [Trait("Category", "Symbols")] - [Fact] - public async Task LanguageServiceFindsFunctionDefinitionInDotSourceReference() - { - SymbolReference definitionResult = - await this.GetDefinition( - FindsFunctionDefinitionInDotSourceReference.SourceDetails).ConfigureAwait(false); - - Assert.True( - definitionResult.FilePath.EndsWith( - FindsFunctionDefinition.SourceDetails.File), - "Unexpected reference file: " + definitionResult.FilePath); - Assert.Equal(1, definitionResult.ScriptRegion.StartLineNumber); - Assert.Equal(10, definitionResult.ScriptRegion.StartColumnNumber); - Assert.Equal("My-Function", definitionResult.SymbolName); - } - - [Trait("Category", "Symbols")] - [Fact] - public async Task LanguageServiceFindsDotSourcedFile() - { - SymbolReference definitionResult = - await this.GetDefinition( - FindsDotSourcedFile.SourceDetails).ConfigureAwait(false); - - Assert.True( - definitionResult.FilePath.EndsWith( - Path.Combine("References", "ReferenceFileE.ps1")), - "Unexpected reference file: " + definitionResult.FilePath); - Assert.Equal(1, definitionResult.ScriptRegion.StartLineNumber); - Assert.Equal(1, definitionResult.ScriptRegion.StartColumnNumber); - Assert.Equal("./ReferenceFileE.ps1", definitionResult.SymbolName); - } - - [Trait("Category", "Symbols")] - [Fact(Skip = "TODO Fix this test. A possible bug in PSES product code.")] - public async Task LanguageServiceFindsFunctionDefinitionInWorkspace() - { - SymbolReference definitionResult = - await this.GetDefinition( - FindsFunctionDefinitionInWorkspace.SourceDetails).ConfigureAwait(false); - Assert.EndsWith("ReferenceFileE.ps1", definitionResult.FilePath); - Assert.Equal("My-FunctionInFileE", definitionResult.SymbolName); - } - - [Trait("Category", "Symbols")] - [Fact] - public async Task LanguageServiceFindsVariableDefinition() - { - SymbolReference definitionResult = - await this.GetDefinition( - FindsVariableDefinition.SourceDetails).ConfigureAwait(false); - - Assert.Equal(6, definitionResult.ScriptRegion.StartLineNumber); - Assert.Equal(1, definitionResult.ScriptRegion.StartColumnNumber); - Assert.Equal("$things", definitionResult.SymbolName); - } - - [Trait("Category", "Symbols")] - [Fact] - public void LanguageServiceFindsOccurrencesOnFunction() - { - IReadOnlyList occurrencesResult = - this.GetOccurrences( - FindsOccurrencesOnFunction.SourceDetails); - - Assert.Equal(3, occurrencesResult.Count()); - Assert.Equal(10, occurrencesResult.Last().ScriptRegion.StartLineNumber); - Assert.Equal(1, occurrencesResult.Last().ScriptRegion.StartColumnNumber); - } - - [Trait("Category", "Symbols")] - [Fact] - public void LanguageServiceFindsOccurrencesOnParameter() - { - IReadOnlyList occurrencesResult = - this.GetOccurrences( - FindOccurrencesOnParameter.SourceDetails); - - Assert.Equal("$myInput", occurrencesResult.Last().SymbolName); - Assert.Equal(2, occurrencesResult.Count()); - Assert.Equal(3, occurrencesResult.Last().ScriptRegion.StartLineNumber); - } - - [Trait("Category", "Symbols")] - [Fact(Skip = "TODO Fix this test. A possible bug in PSES product code.")] - public void LanguageServiceFindsReferencesOnCommandWithAlias() - { - List refsResult = - this.GetReferences( - FindsReferencesOnBuiltInCommandWithAlias.SourceDetails); - - SymbolReference[] foundRefs = refsResult.ToArray(); - Assert.Equal(4, foundRefs.Length); - Assert.Equal("gci", foundRefs[1].SymbolName); - Assert.Equal("Get-ChildItem", foundRefs[foundRefs.Length - 1].SymbolName); - } - - [Trait("Category", "Symbols")] - [Fact(Skip = "TODO Fix this test. A possible bug in PSES product code.")] - public void LanguageServiceFindsReferencesOnAlias() - { - List refsResult = - this.GetReferences( - FindsReferencesOnBuiltInCommandWithAlias.SourceDetails); - - Assert.Equal(4, refsResult.Count()); - Assert.Equal("dir", refsResult.ToArray()[2].SymbolName); - Assert.Equal("Get-ChildItem", refsResult.Last().SymbolName); - } - - [Trait("Category", "Symbols")] - [Fact] - public void LanguageServiceFindsReferencesOnFileWithReferencesFileB() - { - List refsResult = - this.GetReferences( - FindsReferencesOnFunctionMultiFileDotSourceFileB.SourceDetails); - - Assert.Equal(4, refsResult.Count()); - } - - [Trait("Category", "Symbols")] - [Fact] - public void LanguageServiceFindsReferencesOnFileWithReferencesFileC() - { - List refsResult = - this.GetReferences( - FindsReferencesOnFunctionMultiFileDotSourceFileC.SourceDetails); - Assert.Equal(4, refsResult.Count()); - } - - [Trait("Category", "Symbols")] - [Fact] - public async Task LanguageServiceFindsDetailsForBuiltInCommand() - { - SymbolDetails symbolDetails = - await this.symbolsService.FindSymbolDetailsAtLocationAsync( - this.GetScriptFile(FindsDetailsForBuiltInCommand.SourceDetails), - FindsDetailsForBuiltInCommand.SourceDetails.StartLineNumber, - FindsDetailsForBuiltInCommand.SourceDetails.StartColumnNumber).ConfigureAwait(false); - - Assert.NotNull(symbolDetails.Documentation); - Assert.NotEqual("", symbolDetails.Documentation); - } - - [Trait("Category", "Symbols")] - [Fact] - public void LanguageServiceFindsSymbolsInFile() - { - List symbolsResult = - this.FindSymbolsInFile( - FindSymbolsInMultiSymbolFile.SourceDetails); - - Assert.Equal(4, symbolsResult.Where(symbolReference => symbolReference.SymbolType == SymbolType.Function).Count()); - Assert.Equal(3, symbolsResult.Where(symbolReference => symbolReference.SymbolType == SymbolType.Variable).Count()); - Assert.Single(symbolsResult.Where(symbolReference => symbolReference.SymbolType == SymbolType.Workflow)); - - SymbolReference firstFunctionSymbol = symbolsResult.Where(r => r.SymbolType == SymbolType.Function).First(); - Assert.Equal("AFunction", firstFunctionSymbol.SymbolName); - Assert.Equal(7, firstFunctionSymbol.ScriptRegion.StartLineNumber); - Assert.Equal(1, firstFunctionSymbol.ScriptRegion.StartColumnNumber); - - SymbolReference lastVariableSymbol = symbolsResult.Where(r => r.SymbolType == SymbolType.Variable).Last(); - Assert.Equal("$Script:ScriptVar2", lastVariableSymbol.SymbolName); - Assert.Equal(3, lastVariableSymbol.ScriptRegion.StartLineNumber); - Assert.Equal(1, lastVariableSymbol.ScriptRegion.StartColumnNumber); - - SymbolReference firstWorkflowSymbol = symbolsResult.Where(r => r.SymbolType == SymbolType.Workflow).First(); - Assert.Equal("AWorkflow", firstWorkflowSymbol.SymbolName); - Assert.Equal(23, firstWorkflowSymbol.ScriptRegion.StartLineNumber); - Assert.Equal(1, firstWorkflowSymbol.ScriptRegion.StartColumnNumber); - - // TODO: Bring this back when we can use AstVisitor2 again (#276) - //Assert.Equal(1, symbolsResult.FoundOccurrences.Where(r => r.SymbolType == SymbolType.Configuration).Count()); - //SymbolReference firstConfigurationSymbol = symbolsResult.FoundOccurrences.Where(r => r.SymbolType == SymbolType.Configuration).First(); - //Assert.Equal("AConfiguration", firstConfigurationSymbol.SymbolName); - //Assert.Equal(25, firstConfigurationSymbol.ScriptRegion.StartLineNumber); - //Assert.Equal(1, firstConfigurationSymbol.ScriptRegion.StartColumnNumber); - } - - [Trait("Category", "Symbols")] - [Fact] - public void LanguageServiceFindsSymbolsInPesterFile() - { - List symbolsResult = this.FindSymbolsInFile(FindSymbolsInPesterFile.SourceDetails); - Assert.Equal(5, symbolsResult.Count()); - } - - [Trait("Category", "Symbols")] - [Fact] - public void LangServerFindsSymbolsInPSDFile() - { - List symbolsResult = this.FindSymbolsInFile(FindSymbolsInPSDFile.SourceDetails); - Assert.Equal(3, symbolsResult.Count()); - } - - [Trait("Category", "Symbols")] - [Fact] - public void LanguageServiceFindsSymbolsInNoSymbolsFile() - { - List symbolsResult = - this.FindSymbolsInFile( - FindSymbolsInNoSymbolsFile.SourceDetails); - - Assert.Empty(symbolsResult); - } - - private ScriptFile GetScriptFile(ScriptRegion scriptRegion) - { - string resolvedPath = - Path.Combine( - s_baseSharedScriptPath, - scriptRegion.File); - - return - this.workspace.GetFile( - resolvedPath); - } - - private async Task GetCompletionResults(ScriptRegion scriptRegion) - { - // Run the completions request - return - await this.completionHandler.GetCompletionsInFileAsync( - GetScriptFile(scriptRegion), - scriptRegion.StartLineNumber, - scriptRegion.StartColumnNumber).ConfigureAwait(false); - } - - private Task GetParamSetSignatures(ScriptRegion scriptRegion) - { - return this.symbolsService.FindParameterSetsInFileAsync( - GetScriptFile(scriptRegion), - scriptRegion.StartLineNumber, - scriptRegion.StartColumnNumber); - } - - private async Task GetDefinition(ScriptRegion scriptRegion) - { - ScriptFile scriptFile = GetScriptFile(scriptRegion); - - SymbolReference symbolReference = - SymbolsService.FindSymbolAtLocation( - scriptFile, - scriptRegion.StartLineNumber, - scriptRegion.StartColumnNumber); - - Assert.NotNull(symbolReference); - - return - await this.symbolsService.GetDefinitionOfSymbolAsync( - scriptFile, - symbolReference).ConfigureAwait(false); - } - - private List GetReferences(ScriptRegion scriptRegion) - { - ScriptFile scriptFile = GetScriptFile(scriptRegion); - - SymbolReference symbolReference = - SymbolsService.FindSymbolAtLocation( - scriptFile, - scriptRegion.StartLineNumber, - scriptRegion.StartColumnNumber); - - Assert.NotNull(symbolReference); - - return - this.symbolsService.FindReferencesOfSymbol( - symbolReference, - this.workspace.ExpandScriptReferences(scriptFile), - this.workspace); - } - - private IReadOnlyList GetOccurrences(ScriptRegion scriptRegion) - { - return - SymbolsService.FindOccurrencesInFile( - GetScriptFile(scriptRegion), - scriptRegion.StartLineNumber, - scriptRegion.StartColumnNumber); - } - - private List FindSymbolsInFile(ScriptRegion scriptRegion) - { - return - this.symbolsService.FindSymbolsInFile( - GetScriptFile(scriptRegion)); - } - } -} diff --git a/test/PowerShellEditorServices.Test/Language/SymbolsServiceTests.cs b/test/PowerShellEditorServices.Test/Language/SymbolsServiceTests.cs new file mode 100644 index 000000000..d0d58aa17 --- /dev/null +++ b/test/PowerShellEditorServices.Test/Language/SymbolsServiceTests.cs @@ -0,0 +1,305 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging.Abstractions; +using Microsoft.PowerShell.EditorServices.Services; +using Microsoft.PowerShell.EditorServices.Services.PowerShell.Host; +using Microsoft.PowerShell.EditorServices.Services.Symbols; +using Microsoft.PowerShell.EditorServices.Services.TextDocument; +using Microsoft.PowerShell.EditorServices.Test.Shared; +using Microsoft.PowerShell.EditorServices.Test.Shared.Definition; +using Microsoft.PowerShell.EditorServices.Test.Shared.Occurrences; +using Microsoft.PowerShell.EditorServices.Test.Shared.ParameterHint; +using Microsoft.PowerShell.EditorServices.Test.Shared.References; +using Microsoft.PowerShell.EditorServices.Test.Shared.SymbolDetails; +using Microsoft.PowerShell.EditorServices.Test.Shared.Symbols; +using Xunit; + +namespace Microsoft.PowerShell.EditorServices.Test.Language +{ + [Trait("Category", "Symbols")] + public class SymbolsServiceTests: IDisposable + { + private readonly PsesInternalHost psesHost; + private readonly WorkspaceService workspace; + private readonly SymbolsService symbolsService; + + public SymbolsServiceTests() + { + psesHost = PsesHostFactory.Create(NullLoggerFactory.Instance); + workspace = new WorkspaceService(NullLoggerFactory.Instance); + symbolsService = new SymbolsService( + NullLoggerFactory.Instance, + psesHost, + psesHost, + workspace, + new ConfigurationService()); + } + + public void Dispose() + { + psesHost.StopAsync().GetAwaiter().GetResult(); + GC.SuppressFinalize(this); + } + + private ScriptFile GetScriptFile(ScriptRegion scriptRegion) => workspace.GetFile(TestUtilities.GetSharedPath(scriptRegion.File)); + + private Task GetParamSetSignatures(ScriptRegion scriptRegion) + { + return symbolsService.FindParameterSetsInFileAsync( + GetScriptFile(scriptRegion), + scriptRegion.StartLineNumber, + scriptRegion.StartColumnNumber); + } + + private Task GetDefinition(ScriptRegion scriptRegion) + { + ScriptFile scriptFile = GetScriptFile(scriptRegion); + + SymbolReference symbolReference = SymbolsService.FindSymbolAtLocation( + scriptFile, + scriptRegion.StartLineNumber, + scriptRegion.StartColumnNumber); + + Assert.NotNull(symbolReference); + + return symbolsService.GetDefinitionOfSymbolAsync(scriptFile, symbolReference); + } + + private List GetReferences(ScriptRegion scriptRegion) + { + ScriptFile scriptFile = GetScriptFile(scriptRegion); + + SymbolReference symbolReference = SymbolsService.FindSymbolAtLocation( + scriptFile, + scriptRegion.StartLineNumber, + scriptRegion.StartColumnNumber); + + Assert.NotNull(symbolReference); + + return symbolsService.FindReferencesOfSymbol( + symbolReference, + workspace.ExpandScriptReferences(scriptFile), + workspace); + } + + private IReadOnlyList GetOccurrences(ScriptRegion scriptRegion) + { + return SymbolsService.FindOccurrencesInFile( + GetScriptFile(scriptRegion), + scriptRegion.StartLineNumber, + scriptRegion.StartColumnNumber); + } + + private List FindSymbolsInFile(ScriptRegion scriptRegion) => symbolsService.FindSymbolsInFile(GetScriptFile(scriptRegion)); + + [Fact] + public async Task FindsParameterHintsOnCommand() + { + ParameterSetSignatures paramSignatures = await GetParamSetSignatures(FindsParameterSetsOnCommandData.SourceDetails).ConfigureAwait(true); + Assert.NotNull(paramSignatures); + Assert.Equal("Get-Process", paramSignatures.CommandName); + Assert.Equal(6, paramSignatures.Signatures.Length); + } + + [Fact] + public async Task FindsCommandForParamHintsWithSpaces() + { + ParameterSetSignatures paramSignatures = await GetParamSetSignatures(FindsParameterSetsOnCommandWithSpacesData.SourceDetails).ConfigureAwait(true); + Assert.NotNull(paramSignatures); + Assert.Equal("Write-Host", paramSignatures.CommandName); + Assert.Single(paramSignatures.Signatures); + } + + [Fact] + public async Task FindsFunctionDefinition() + { + SymbolReference definitionResult = await GetDefinition(FindsFunctionDefinitionData.SourceDetails).ConfigureAwait(true); + Assert.Equal(1, definitionResult.ScriptRegion.StartLineNumber); + Assert.Equal(10, definitionResult.ScriptRegion.StartColumnNumber); + Assert.Equal("My-Function", definitionResult.SymbolName); + } + + [Fact] + public void FindsReferencesOnFunction() + { + List referencesResult = GetReferences(FindsReferencesOnFunctionData.SourceDetails); + Assert.Equal(3, referencesResult.Count); + Assert.Equal(1, referencesResult[0].ScriptRegion.StartLineNumber); + Assert.Equal(10, referencesResult[0].ScriptRegion.StartColumnNumber); + } + + [Fact] + public async Task FindsFunctionDefinitionInDotSourceReference() + { + SymbolReference definitionResult = await GetDefinition(FindsFunctionDefinitionInDotSourceReferenceData.SourceDetails).ConfigureAwait(true); + Assert.True( + definitionResult.FilePath.EndsWith(FindsFunctionDefinitionData.SourceDetails.File), + "Unexpected reference file: " + definitionResult.FilePath); + Assert.Equal(1, definitionResult.ScriptRegion.StartLineNumber); + Assert.Equal(10, definitionResult.ScriptRegion.StartColumnNumber); + Assert.Equal("My-Function", definitionResult.SymbolName); + } + + [Fact] + public async Task FindsDotSourcedFile() + { + SymbolReference definitionResult = await GetDefinition(FindsDotSourcedFileData.SourceDetails).ConfigureAwait(true); + Assert.True( + definitionResult.FilePath.EndsWith(Path.Combine("References", "ReferenceFileE.ps1")), + "Unexpected reference file: " + definitionResult.FilePath); + Assert.Equal(1, definitionResult.ScriptRegion.StartLineNumber); + Assert.Equal(1, definitionResult.ScriptRegion.StartColumnNumber); + Assert.Equal("./ReferenceFileE.ps1", definitionResult.SymbolName); + } + + [Fact] + public async Task FindsFunctionDefinitionInWorkspace() + { + workspace.WorkspacePath = TestUtilities.GetSharedPath("References"); + SymbolReference definitionResult = await GetDefinition(FindsFunctionDefinitionInWorkspaceData.SourceDetails).ConfigureAwait(true); + Assert.EndsWith("ReferenceFileE.ps1", definitionResult.FilePath); + Assert.Equal("My-FunctionInFileE", definitionResult.SymbolName); + } + + [Fact] + public async Task FindsVariableDefinition() + { + SymbolReference definitionResult = await GetDefinition(FindsVariableDefinitionData.SourceDetails).ConfigureAwait(true); + Assert.Equal(6, definitionResult.ScriptRegion.StartLineNumber); + Assert.Equal(1, definitionResult.ScriptRegion.StartColumnNumber); + Assert.Equal("$things", definitionResult.SymbolName); + } + + [Fact] + public void FindsReferencesOnVariable() + { + List referencesResult = GetReferences(FindsReferencesOnVariableData.SourceDetails); + Assert.Equal(3, referencesResult.Count); + Assert.Equal(10, referencesResult[referencesResult.Count - 1].ScriptRegion.StartLineNumber); + Assert.Equal(13, referencesResult[referencesResult.Count - 1].ScriptRegion.StartColumnNumber); + } + + [Fact] + public void FindsOccurrencesOnFunction() + { + IReadOnlyList occurrencesResult = GetOccurrences(FindsOccurrencesOnFunctionData.SourceDetails); + Assert.Equal(3, occurrencesResult.Count); + Assert.Equal(10, occurrencesResult[occurrencesResult.Count - 1].ScriptRegion.StartLineNumber); + Assert.Equal(1, occurrencesResult[occurrencesResult.Count - 1].ScriptRegion.StartColumnNumber); + } + + [Fact] + public void FindsOccurrencesOnParameter() + { + IReadOnlyList occurrencesResult = GetOccurrences(FindOccurrencesOnParameterData.SourceDetails); + Assert.Equal(2, occurrencesResult.Count); + Assert.Equal("$myInput", occurrencesResult[occurrencesResult.Count - 1].SymbolName); + Assert.Equal(3, occurrencesResult[occurrencesResult.Count - 1].ScriptRegion.StartLineNumber); + } + + [Fact(Skip = "TODO Fix this test. A possible bug in PSES product code.")] + public void FindsReferencesOnCommandWithAlias() + { + List referencesResult = GetReferences(FindsReferencesOnBuiltInCommandWithAliasData.SourceDetails); + Assert.Equal(4, referencesResult.Count); + Assert.Equal("gci", referencesResult[1].SymbolName); + Assert.Equal("Get-ChildItem", referencesResult[referencesResult.Count - 1].SymbolName); + } + + [Fact(Skip = "TODO Fix this test. A possible bug in PSES product code.")] + public void FindsReferencesOnAlias() + { + List referencesResult = GetReferences(FindsReferencesOnBuiltInCommandWithAliasData.SourceDetails); + Assert.Equal(4, referencesResult.Count); + Assert.Equal("dir", referencesResult[2].SymbolName); + Assert.Equal("Get-ChildItem", referencesResult[referencesResult.Count - 1].SymbolName); + } + + [Fact] + public void FindsReferencesOnFileWithReferencesFileB() + { + List referencesResult = GetReferences(FindsReferencesOnFunctionMultiFileDotSourceFileB.SourceDetails); + Assert.Equal(4, referencesResult.Count); + } + + [Fact] + public void FindsReferencesOnFileWithReferencesFileC() + { + List referencesResult = GetReferences(FindsReferencesOnFunctionMultiFileDotSourceFileC.SourceDetails); + Assert.Equal(4, referencesResult.Count); + } + + [Fact] + public async Task FindsDetailsForBuiltInCommand() + { + SymbolDetails symbolDetails = await symbolsService.FindSymbolDetailsAtLocationAsync( + GetScriptFile(FindsDetailsForBuiltInCommandData.SourceDetails), + FindsDetailsForBuiltInCommandData.SourceDetails.StartLineNumber, + FindsDetailsForBuiltInCommandData.SourceDetails.StartColumnNumber).ConfigureAwait(true); + + Assert.NotNull(symbolDetails.Documentation); + Assert.NotEqual("", symbolDetails.Documentation); + } + + [Fact] + public void FindsSymbolsInFile() + { + List symbolsResult = + FindSymbolsInFile( + FindSymbolsInMultiSymbolFile.SourceDetails); + + Assert.Equal(4, symbolsResult.Count(symbolReference => symbolReference.SymbolType == SymbolType.Function)); + Assert.Equal(3, symbolsResult.Count(symbolReference => symbolReference.SymbolType == SymbolType.Variable)); + Assert.Single(symbolsResult.Where(symbolReference => symbolReference.SymbolType == SymbolType.Workflow)); + + SymbolReference firstFunctionSymbol = symbolsResult.First(r => r.SymbolType == SymbolType.Function); + Assert.Equal("AFunction", firstFunctionSymbol.SymbolName); + Assert.Equal(7, firstFunctionSymbol.ScriptRegion.StartLineNumber); + Assert.Equal(1, firstFunctionSymbol.ScriptRegion.StartColumnNumber); + + SymbolReference lastVariableSymbol = symbolsResult.Last(r => r.SymbolType == SymbolType.Variable); + Assert.Equal("$Script:ScriptVar2", lastVariableSymbol.SymbolName); + Assert.Equal(3, lastVariableSymbol.ScriptRegion.StartLineNumber); + Assert.Equal(1, lastVariableSymbol.ScriptRegion.StartColumnNumber); + + SymbolReference firstWorkflowSymbol = symbolsResult.First(r => r.SymbolType == SymbolType.Workflow); + Assert.Equal("AWorkflow", firstWorkflowSymbol.SymbolName); + Assert.Equal(23, firstWorkflowSymbol.ScriptRegion.StartLineNumber); + Assert.Equal(1, firstWorkflowSymbol.ScriptRegion.StartColumnNumber); + + // TODO: Bring this back when we can use AstVisitor2 again (#276) + //Assert.Equal(1, symbolsResult.FoundOccurrences.Where(r => r.SymbolType == SymbolType.Configuration).Count()); + //SymbolReference firstConfigurationSymbol = symbolsResult.FoundOccurrences.Where(r => r.SymbolType == SymbolType.Configuration).First(); + //Assert.Equal("AConfiguration", firstConfigurationSymbol.SymbolName); + //Assert.Equal(25, firstConfigurationSymbol.ScriptRegion.StartLineNumber); + //Assert.Equal(1, firstConfigurationSymbol.ScriptRegion.StartColumnNumber); + } + + [Fact] + public void FindsSymbolsInPesterFile() + { + List symbolsResult = FindSymbolsInFile(FindSymbolsInPesterFile.SourceDetails); + Assert.Equal(5, symbolsResult.Count); + } + + [Fact] + public void LangServerFindsSymbolsInPSDFile() + { + List symbolsResult = FindSymbolsInFile(FindSymbolsInPSDFile.SourceDetails); + Assert.Equal(3, symbolsResult.Count); + } + + [Fact] + public void FindsSymbolsInNoSymbolsFile() + { + List symbolsResult = FindSymbolsInFile(FindSymbolsInNoSymbolsFile.SourceDetails); + Assert.Empty(symbolsResult); + } + } +}