diff --git a/src/PowerShellEditorServices.Host/CodeLens/CodeLensFeature.cs b/src/PowerShellEditorServices.Host/CodeLens/CodeLensFeature.cs
index e7e2f6910..3f9c11c88 100644
--- a/src/PowerShellEditorServices.Host/CodeLens/CodeLensFeature.cs
+++ b/src/PowerShellEditorServices.Host/CodeLens/CodeLensFeature.cs
@@ -8,8 +8,6 @@
using Microsoft.PowerShell.EditorServices.Protocol.MessageProtocol;
using Microsoft.PowerShell.EditorServices.Utility;
using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
-using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@@ -99,11 +97,11 @@ private CodeLensFeature(
///
/// The PowerShell script file to get CodeLenses for.
/// All generated CodeLenses for the given script file.
- public CodeLens[] ProvideCodeLenses(ScriptFile scriptFile)
+ public async Task ProvideCodeLenses(ScriptFile scriptFile)
{
- return InvokeProviders(provider => provider.ProvideCodeLenses(scriptFile))
- .SelectMany(codeLens => codeLens)
- .ToArray();
+ var providers = await Task.WhenAll(InvokeProviders(async provider => await provider.ProvideCodeLenses(scriptFile)));
+ return providers.SelectMany(codeLens => codeLens)
+ .ToArray();
}
///
@@ -118,7 +116,7 @@ private async Task HandleCodeLensRequestAsync(
ScriptFile scriptFile = _editorSession.Workspace.GetFile(
codeLensParams.TextDocument.Uri);
- CodeLens[] codeLensResults = ProvideCodeLenses(scriptFile);
+ CodeLens[] codeLensResults = await ProvideCodeLenses(scriptFile);
var codeLensResponse = new LanguageServer.CodeLens[codeLensResults.Length];
for (int i = 0; i < codeLensResults.Length; i++)
diff --git a/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs b/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs
index 619ca0a49..83829896e 100644
--- a/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs
+++ b/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs
@@ -8,6 +8,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Management.Automation;
using System.Threading;
using System.Threading.Tasks;
@@ -25,6 +26,12 @@ internal class PesterCodeLensProvider : FeatureProviderBase, ICodeLensProvider
///
private IDocumentSymbolProvider _symbolProvider;
+ ///
+ /// Pester 4.6.0 introduced a new ScriptblockFilter parameter to be able to run a test based on a line,
+ /// therefore knowing this information is important.
+ ///
+ private readonly Lazy> _pesterV4_6_0_OrHigherAvailable;
+
///
/// Create a new Pester CodeLens provider for a given editor session.
///
@@ -33,6 +40,7 @@ public PesterCodeLensProvider(EditorSession editorSession)
{
_editorSession = editorSession;
_symbolProvider = new PesterDocumentSymbolProvider();
+ _pesterV4_6_0_OrHigherAvailable = new Lazy>(async () => await DeterminePesterVersion());
}
///
@@ -41,10 +49,13 @@ public PesterCodeLensProvider(EditorSession editorSession)
/// The Pester symbol to get CodeLenses for.
/// The script file the Pester symbol comes from.
/// All CodeLenses for the given Pester symbol.
- private CodeLens[] GetPesterLens(
+ private async Task GetPesterLens(
PesterSymbolReference pesterSymbol,
ScriptFile scriptFile)
{
+ // A value of null is a signal to PSES that the available Pester version does not support
+ // running Describe blocks by name (the test name will used instead then).
+ int? describeBlockLineNumber = await _pesterV4_6_0_OrHigherAvailable.Value ? (int?)pesterSymbol.ScriptRegion.StartLineNumber : null;
var codeLensResults = new CodeLens[]
{
new CodeLens(
@@ -54,7 +65,7 @@ private CodeLens[] GetPesterLens(
new ClientCommand(
"PowerShell.RunPesterTests",
"Run tests",
- new object[] { scriptFile.ClientFilePath, false /* No debug */, pesterSymbol.TestName })),
+ new object[] { scriptFile.ClientFilePath, false /* No debug */, pesterSymbol.TestName, describeBlockLineNumber })),
new CodeLens(
this,
@@ -63,18 +74,45 @@ private CodeLens[] GetPesterLens(
new ClientCommand(
"PowerShell.RunPesterTests",
"Debug tests",
- new object[] { scriptFile.ClientFilePath, true /* Run in debugger */, pesterSymbol.TestName })),
+ new object[] { scriptFile.ClientFilePath, true /* Run in debugger */, pesterSymbol.TestName, describeBlockLineNumber })),
};
return codeLensResults;
}
+ ///
+ /// Used to determine the value of as a background task.
+ ///
+ private async Task DeterminePesterVersion()
+ {
+ var powerShell = new PSCommand()
+ .AddCommand("Get-Command")
+ .AddParameter("Name", "Invoke-Pester");
+
+ IEnumerable result = await _editorSession.PowerShellContext.ExecuteCommandAsync(powerShell);
+ var pesterCommand = result.FirstOrDefault();
+ if (pesterCommand == null)
+ {
+ return false;
+ }
+
+ if (pesterCommand.BaseObject is FunctionInfo invokePesterFunction)
+ {
+ var pesterVersion = invokePesterFunction.Version;
+ if (pesterVersion.Major >= 4 && pesterVersion.Minor >= 6)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
///
/// Get all Pester CodeLenses for a given script file.
///
/// The script file to get Pester CodeLenses for.
/// All Pester CodeLenses for the given script file.
- public CodeLens[] ProvideCodeLenses(ScriptFile scriptFile)
+ public async Task ProvideCodeLenses(ScriptFile scriptFile)
{
var lenses = new List();
foreach (SymbolReference symbol in _symbolProvider.ProvideDocumentSymbols(scriptFile))
@@ -86,7 +124,7 @@ public CodeLens[] ProvideCodeLenses(ScriptFile scriptFile)
continue;
}
- lenses.AddRange(GetPesterLens(pesterSymbol, scriptFile));
+ lenses.AddRange(await GetPesterLens(pesterSymbol, scriptFile));
}
}
diff --git a/src/PowerShellEditorServices.Host/CodeLens/ReferencesCodeLensProvider.cs b/src/PowerShellEditorServices.Host/CodeLens/ReferencesCodeLensProvider.cs
index 6a5312a93..fa99bca71 100644
--- a/src/PowerShellEditorServices.Host/CodeLens/ReferencesCodeLensProvider.cs
+++ b/src/PowerShellEditorServices.Host/CodeLens/ReferencesCodeLensProvider.cs
@@ -5,7 +5,6 @@
using System;
using System.Collections.Generic;
-using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
@@ -50,7 +49,7 @@ public ReferencesCodeLensProvider(EditorSession editorSession)
///
/// The PowerShell script file to get code lenses for.
/// An array of CodeLenses describing all functions in the given script file.
- public CodeLens[] ProvideCodeLenses(ScriptFile scriptFile)
+ public async Task ProvideCodeLenses(ScriptFile scriptFile)
{
var acc = new List();
foreach (SymbolReference sym in _symbolProvider.ProvideDocumentSymbols(scriptFile))
diff --git a/src/PowerShellEditorServices/CodeLenses/ICodeLensProvider.cs b/src/PowerShellEditorServices/CodeLenses/ICodeLensProvider.cs
index 71a1c0243..76245b969 100644
--- a/src/PowerShellEditorServices/CodeLenses/ICodeLensProvider.cs
+++ b/src/PowerShellEditorServices/CodeLenses/ICodeLensProvider.cs
@@ -3,9 +3,6 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
-using Microsoft.PowerShell.EditorServices.Utility;
-using System.Collections.Generic;
-using System.Management.Automation.Language;
using System.Threading;
using System.Threading.Tasks;
@@ -24,7 +21,7 @@ public interface ICodeLensProvider : IFeatureProvider
/// The document for which CodeLenses should be provided.
///
/// An array of CodeLenses.
- CodeLens[] ProvideCodeLenses(ScriptFile scriptFile);
+ Task ProvideCodeLenses(ScriptFile scriptFile);
///
/// Resolves a CodeLens that was created without a Command.
diff --git a/src/PowerShellEditorServices/CodeLenses/ICodeLenses.cs b/src/PowerShellEditorServices/CodeLenses/ICodeLenses.cs
index f63319c1c..e69a05fed 100644
--- a/src/PowerShellEditorServices/CodeLenses/ICodeLenses.cs
+++ b/src/PowerShellEditorServices/CodeLenses/ICodeLenses.cs
@@ -3,8 +3,6 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
-using System.Collections.Generic;
-using System.Threading;
using System.Threading.Tasks;
namespace Microsoft.PowerShell.EditorServices.CodeLenses
@@ -29,6 +27,6 @@ public interface ICodeLenses
/// The document for which CodeLenses should be provided.
///
/// An array of CodeLenses.
- CodeLens[] ProvideCodeLenses(ScriptFile scriptFile);
+ Task ProvideCodeLenses(ScriptFile scriptFile);
}
}