diff --git a/src/PowerShellEditorServices/Services/CodeLens/PesterCodeLensProvider.cs b/src/PowerShellEditorServices/Services/CodeLens/PesterCodeLensProvider.cs index d927dd90e..421f11ead 100644 --- a/src/PowerShellEditorServices/Services/CodeLens/PesterCodeLensProvider.cs +++ b/src/PowerShellEditorServices/Services/CodeLens/PesterCodeLensProvider.cs @@ -3,7 +3,9 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // +using System; using System.Collections.Generic; +using Microsoft.PowerShell.EditorServices.Services; using Microsoft.PowerShell.EditorServices.Services.Symbols; using Microsoft.PowerShell.EditorServices.Services.TextDocument; using Microsoft.PowerShell.EditorServices.Utility; @@ -14,6 +16,7 @@ namespace Microsoft.PowerShell.EditorServices.CodeLenses { internal class PesterCodeLensProvider : ICodeLensProvider { + private readonly ConfigurationService _configurationService; /// /// The symbol provider to get symbols from to build code lenses with. @@ -29,8 +32,9 @@ internal class PesterCodeLensProvider : ICodeLensProvider /// /// Create a new Pester CodeLens provider for a given editor session. /// - public PesterCodeLensProvider() + public PesterCodeLensProvider(ConfigurationService configurationService) { + _configurationService = configurationService; _symbolProvider = new PesterDocumentSymbolProvider(); } @@ -42,7 +46,7 @@ public PesterCodeLensProvider() /// All CodeLenses for the given Pester symbol. private CodeLens[] GetPesterLens(PesterSymbolReference pesterSymbol, ScriptFile scriptFile) { - + string word = pesterSymbol.Command == PesterCommandType.It ? "test" : "tests"; var codeLensResults = new CodeLens[] { new CodeLens() @@ -55,7 +59,7 @@ private CodeLens[] GetPesterLens(PesterSymbolReference pesterSymbol, ScriptFile Command = new Command() { Name = "PowerShell.RunPesterTests", - Title = "Run tests", + Title = $"Run {word}", Arguments = JArray.FromObject(new object[] { scriptFile.DocumentUri, false /* No debug */, @@ -74,7 +78,7 @@ private CodeLens[] GetPesterLens(PesterSymbolReference pesterSymbol, ScriptFile Command = new Command() { Name = "PowerShell.RunPesterTests", - Title = "Debug tests", + Title = $"Debug {word}", Arguments = JArray.FromObject(new object[] { scriptFile.DocumentUri, true /* No debug */, @@ -97,15 +101,18 @@ public CodeLens[] ProvideCodeLenses(ScriptFile scriptFile) var lenses = new List(); foreach (SymbolReference symbol in _symbolProvider.ProvideDocumentSymbols(scriptFile)) { - if (symbol is PesterSymbolReference pesterSymbol) + if (!(symbol is PesterSymbolReference pesterSymbol)) { - if (pesterSymbol.Command != PesterCommandType.Describe) - { - continue; - } + continue; + } - lenses.AddRange(GetPesterLens(pesterSymbol, scriptFile)); + if (_configurationService.CurrentSettings.Pester.UseLegacyCodeLens + && pesterSymbol.Command != PesterCommandType.Describe) + { + continue; } + + lenses.AddRange(GetPesterLens(pesterSymbol, scriptFile)); } return lenses.ToArray(); diff --git a/src/PowerShellEditorServices/Services/Symbols/SymbolsService.cs b/src/PowerShellEditorServices/Services/Symbols/SymbolsService.cs index b9e959f87..65ad2fb07 100644 --- a/src/PowerShellEditorServices/Services/Symbols/SymbolsService.cs +++ b/src/PowerShellEditorServices/Services/Symbols/SymbolsService.cs @@ -51,7 +51,8 @@ internal class SymbolsService public SymbolsService( ILoggerFactory factory, PowerShellContextService powerShellContextService, - WorkspaceService workspaceService) + WorkspaceService workspaceService, + ConfigurationService configurationService) { _logger = factory.CreateLogger(); _powerShellContextService = powerShellContextService; @@ -61,7 +62,7 @@ public SymbolsService( var codeLensProviders = new ICodeLensProvider[] { new ReferencesCodeLensProvider(_workspaceService, this), - new PesterCodeLensProvider(), + new PesterCodeLensProvider(configurationService), }; foreach (ICodeLensProvider codeLensProvider in codeLensProviders) { diff --git a/src/PowerShellEditorServices/Services/TextDocument/Handlers/CodeLensHandlers.cs b/src/PowerShellEditorServices/Services/TextDocument/Handlers/CodeLensHandlers.cs index 3eab5a280..334b4b913 100644 --- a/src/PowerShellEditorServices/Services/TextDocument/Handlers/CodeLensHandlers.cs +++ b/src/PowerShellEditorServices/Services/TextDocument/Handlers/CodeLensHandlers.cs @@ -30,7 +30,7 @@ internal class CodeLensHandlers : ICodeLensHandler, ICodeLensResolveHandler private CodeLensCapability _capability; - public CodeLensHandlers(ILoggerFactory factory, SymbolsService symbolsService, WorkspaceService workspaceService) + public CodeLensHandlers(ILoggerFactory factory, SymbolsService symbolsService, WorkspaceService workspaceService, ConfigurationService configurationService) { _logger = factory.CreateLogger(); _workspaceService = workspaceService; diff --git a/src/PowerShellEditorServices/Services/Workspace/LanguageServerSettings.cs b/src/PowerShellEditorServices/Services/Workspace/LanguageServerSettings.cs index 50902935e..14776c6e1 100644 --- a/src/PowerShellEditorServices/Services/Workspace/LanguageServerSettings.cs +++ b/src/PowerShellEditorServices/Services/Workspace/LanguageServerSettings.cs @@ -26,11 +26,14 @@ internal class LanguageServerSettings public CodeFoldingSettings CodeFolding { get; set; } + public PesterSettings Pester { get; set; } + public LanguageServerSettings() { this.ScriptAnalysis = new ScriptAnalysisSettings(); this.CodeFormatting = new CodeFormattingSettings(); this.CodeFolding = new CodeFoldingSettings(); + this.Pester = new PesterSettings(); } public void Update( @@ -49,6 +52,7 @@ public void Update( logger); this.CodeFormatting = new CodeFormattingSettings(settings.CodeFormatting); this.CodeFolding.Update(settings.CodeFolding, logger); + this.Pester = new PesterSettings(settings.Pester); } } } @@ -356,6 +360,26 @@ public void Update( } } + /// + /// Pester settings + /// + public class PesterSettings + { + public PesterSettings() + { + } + + public PesterSettings(PesterSettings settings) + { + UseLegacyCodeLens = settings.UseLegacyCodeLens; + } + + /// + /// Whether integration features specific to Pester v5 are enabled + /// + public bool UseLegacyCodeLens { get; set; } + } + /// /// Additional settings from the Language Client that affect Language Server operations but /// do not exist under the 'powershell' section diff --git a/test/PowerShellEditorServices.Test.E2E/LSPTestsFixures.cs b/test/PowerShellEditorServices.Test.E2E/LSPTestsFixures.cs index 7121a71e8..b59101e87 100644 --- a/test/PowerShellEditorServices.Test.E2E/LSPTestsFixures.cs +++ b/test/PowerShellEditorServices.Test.E2E/LSPTestsFixures.cs @@ -32,9 +32,9 @@ public async override Task CustomInitializeAsync( // Make sure Script Analysis is enabled because we'll need it in the tests. LanguageClient.Workspace.DidChangeConfiguration(JObject.Parse(@" { - ""PowerShell"": { - ""ScriptAnalysis"": { - ""Enable"": true + ""powershell"": { + ""scriptAnalysis"": { + ""enable"": true } } } diff --git a/test/PowerShellEditorServices.Test.E2E/LanguageServerProtocolMessageTests.cs b/test/PowerShellEditorServices.Test.E2E/LanguageServerProtocolMessageTests.cs index 0c1e4afe7..8e1501814 100644 --- a/test/PowerShellEditorServices.Test.E2E/LanguageServerProtocolMessageTests.cs +++ b/test/PowerShellEditorServices.Test.E2E/LanguageServerProtocolMessageTests.cs @@ -198,9 +198,9 @@ public async Task CanReceiveDiagnosticsFromConfigurationChange() { Settings = JToken.Parse(@" { - ""PowerShell"": { - ""ScriptAnalysis"": { - ""Enable"": false + ""powershell"": { + ""scriptAnalysis"": { + ""enable"": false } } } @@ -216,9 +216,9 @@ public async Task CanReceiveDiagnosticsFromConfigurationChange() { Settings = JToken.Parse(@" { - ""PowerShell"": { - ""ScriptAnalysis"": { - ""Enable"": true + ""powershell"": { + ""scriptAnalysis"": { + ""enable"": true } } } @@ -550,8 +550,19 @@ await LanguageClient.SendRequest( } [Fact] - public async Task CanSendPesterCodeLensRequest() + public async Task CanSendPesterLegacyCodeLensRequest() { + // Make sure LegacyCodeLens is enabled because we'll need it in this test. + LanguageClient.Workspace.DidChangeConfiguration(JObject.Parse(@" +{ + ""powershell"": { + ""pester"": { + ""useLegacyCodeLens"": true + } + } +} +")); + string filePath = NewTestFile(@" Describe 'DescribeName' { Context 'ContextName' { @@ -597,6 +608,109 @@ public async Task CanSendPesterCodeLensRequest() }); } + [Fact] + public async Task CanSendPesterCodeLensRequest() + { + // Make sure Pester legacy CodeLens is disabled because we'll need it in this test. + LanguageClient.Workspace.DidChangeConfiguration(JObject.Parse(@" + { + ""powershell"": { + ""pester"": { + ""useLegacyCodeLens"": false + } + } + } + ")); + + string filePath = NewTestFile(@" +Describe 'DescribeName' { + Context 'ContextName' { + It 'ItName' { + 1 | Should - Be 1 + } + } +} +", isPester: true); + + CodeLensContainer codeLenses = await LanguageClient.SendRequest( + "textDocument/codeLens", + new CodeLensParams + { + TextDocument = new TextDocumentIdentifier + { + Uri = new Uri(filePath) + } + }); + + Assert.Collection(codeLenses, + codeLens => + { + Range range = codeLens.Range; + + Assert.Equal(1, range.Start.Line); + Assert.Equal(0, range.Start.Character); + Assert.Equal(7, range.End.Line); + Assert.Equal(1, range.End.Character); + + Assert.Equal("Run tests", codeLens.Command.Title); + }, + codeLens => + { + Range range = codeLens.Range; + + Assert.Equal(1, range.Start.Line); + Assert.Equal(0, range.Start.Character); + Assert.Equal(7, range.End.Line); + Assert.Equal(1, range.End.Character); + + Assert.Equal("Debug tests", codeLens.Command.Title); + }, + codeLens => + { + Range range = codeLens.Range; + + Assert.Equal(2, range.Start.Line); + Assert.Equal(4, range.Start.Character); + Assert.Equal(6, range.End.Line); + Assert.Equal(5, range.End.Character); + + Assert.Equal("Run tests", codeLens.Command.Title); + }, + codeLens => + { + Range range = codeLens.Range; + + Assert.Equal(2, range.Start.Line); + Assert.Equal(4, range.Start.Character); + Assert.Equal(6, range.End.Line); + Assert.Equal(5, range.End.Character); + + Assert.Equal("Debug tests", codeLens.Command.Title); + }, + codeLens => + { + Range range = codeLens.Range; + + Assert.Equal(3, range.Start.Line); + Assert.Equal(8, range.Start.Character); + Assert.Equal(5, range.End.Line); + Assert.Equal(9, range.End.Character); + + Assert.Equal("Run test", codeLens.Command.Title); + }, + codeLens => + { + Range range = codeLens.Range; + + Assert.Equal(3, range.Start.Line); + Assert.Equal(8, range.Start.Character); + Assert.Equal(5, range.End.Line); + Assert.Equal(9, range.End.Character); + + Assert.Equal("Debug test", codeLens.Command.Title); + }); + } + [Fact] public async Task CanSendReferencesCodeLensRequest() { diff --git a/test/PowerShellEditorServices.Test/Language/LanguageServiceTests.cs b/test/PowerShellEditorServices.Test/Language/LanguageServiceTests.cs index b18123862..9cd3a786e 100644 --- a/test/PowerShellEditorServices.Test/Language/LanguageServiceTests.cs +++ b/test/PowerShellEditorServices.Test/Language/LanguageServiceTests.cs @@ -46,7 +46,7 @@ public LanguageServiceTests() var logger = NullLogger.Instance; powerShellContext = PowerShellContextFactory.Create(logger); workspace = new WorkspaceService(NullLoggerFactory.Instance); - symbolsService = new SymbolsService(NullLoggerFactory.Instance, powerShellContext, workspace); + symbolsService = new SymbolsService(NullLoggerFactory.Instance, powerShellContext, workspace, new ConfigurationService()); completionHandler = new CompletionHandler(NullLoggerFactory.Instance, powerShellContext, workspace); }