diff --git a/PowerShellEditorServices.build.ps1 b/PowerShellEditorServices.build.ps1 index fea8c0340..b75cb7e10 100644 --- a/PowerShellEditorServices.build.ps1 +++ b/PowerShellEditorServices.build.ps1 @@ -197,7 +197,9 @@ task LayoutModule -After Build { Copy-Item -Force -Path $PSScriptRoot\src\PowerShellEditorServices.Host\bin\$Configuration\net451\Newtonsoft.Json.dll -Destination $PSScriptRoot\module\PowerShellEditorServices\bin\Desktop\ } Copy-Item -Force -Path $PSScriptRoot\src\PowerShellEditorServices.Host\bin\$Configuration\netstandard1.6\* -Filter Microsoft.PowerShell.EditorServices*.dll -Destination $PSScriptRoot\module\PowerShellEditorServices\bin\Core\ +} +task BuildCmdletHelp { New-ExternalHelp -Path $PSScriptRoot\module\docs -OutputPath $PSScriptRoot\module\PowerShellEditorServices\Commands\en-US -Force } @@ -225,4 +227,4 @@ task UploadArtifacts -If ($script:IsCIBuild) { } # The default task is to run the entire CI build -task . GetProductVersion, Clean, Build, TestPowerShellApi, CITest, PackageNuGet, PackageModule, UploadArtifacts +task . GetProductVersion, Clean, Build, TestPowerShellApi, CITest, BuildCmdletHelp, PackageNuGet, PackageModule, UploadArtifacts diff --git a/src/PowerShellEditorServices.Host/CodeLens/CodeLensFeature.cs b/src/PowerShellEditorServices.Host/CodeLens/CodeLensFeature.cs index 9f6008694..f7631376e 100644 --- a/src/PowerShellEditorServices.Host/CodeLens/CodeLensFeature.cs +++ b/src/PowerShellEditorServices.Host/CodeLens/CodeLensFeature.cs @@ -58,6 +58,9 @@ public static CodeLensFeature Create( new ReferencesCodeLensProvider( editorSession)); + codeLenses.Providers.Add( + new PesterCodeLensProvider( + editorSession)); editorSession.Components.Register(codeLenses); diff --git a/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs b/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs new file mode 100644 index 000000000..3487a1660 --- /dev/null +++ b/src/PowerShellEditorServices.Host/CodeLens/PesterCodeLensProvider.cs @@ -0,0 +1,99 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +using Microsoft.PowerShell.EditorServices.Commands; +using Microsoft.PowerShell.EditorServices.Symbols; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace Microsoft.PowerShell.EditorServices.CodeLenses +{ + internal class PesterCodeLensProvider : FeatureProviderBase, ICodeLensProvider + { + private static char[] QuoteChars = new char[] { '\'', '"'}; + + private EditorSession editorSession; + private IDocumentSymbolProvider symbolProvider; + + public PesterCodeLensProvider(EditorSession editorSession) + { + this.editorSession = editorSession; + this.symbolProvider = new PesterDocumentSymbolProvider(); + } + + private IEnumerable GetPesterLens( + SymbolReference symbol, + ScriptFile scriptFile) + { + // Trim the Describe "" { from the symbol name + int startQuoteIndex = symbol.SourceLine.IndexOfAny(QuoteChars) + 1; + int endQuoteIndex = symbol.SourceLine.LastIndexOfAny(QuoteChars); + + string describeBlockName = + symbol.SourceLine.Substring( + startQuoteIndex, + endQuoteIndex - startQuoteIndex); + + var clientCommands = new ClientCommand[] + { + new ClientCommand( + "PowerShell.RunPesterTests", + "run tests", + new object[] + { + scriptFile.ClientFilePath, + false, // Don't debug + describeBlockName, + }), + + new ClientCommand( + "PowerShell.RunPesterTests", + "debug tests", + new object[] + { + scriptFile.ClientFilePath, + true, // Run in debugger + describeBlockName, + }), + }; + + return + clientCommands.Select( + command => + new CodeLens( + this, + scriptFile, + symbol.ScriptRegion, + command)); + } + + public CodeLens[] ProvideCodeLenses(ScriptFile scriptFile) + { + var symbols = + this.symbolProvider + .ProvideDocumentSymbols(scriptFile); + + var lenses = + symbols + .Where(s => s.SymbolName.StartsWith("Describe")) + .SelectMany(s => this.GetPesterLens(s, scriptFile)) + .ToArray(); + + return lenses; + } + + public Task ResolveCodeLensAsync( + CodeLens codeLens, + CancellationToken cancellationToken) + { + // This provider has no specific behavior for + // resolving CodeLenses. + return Task.FromResult(codeLens); + } + } +} diff --git a/src/PowerShellEditorServices/Language/SymbolReference.cs b/src/PowerShellEditorServices/Language/SymbolReference.cs index 2927fa82a..af0551a9e 100644 --- a/src/PowerShellEditorServices/Language/SymbolReference.cs +++ b/src/PowerShellEditorServices/Language/SymbolReference.cs @@ -48,14 +48,20 @@ public class SymbolReference /// Constructs and instance of a SymbolReference /// /// The higher level type of the symbol + /// The name of the symbol /// The script extent of the symbol /// The file path of the symbol /// The line contents of the given symbol (defaults to empty string) - public SymbolReference(SymbolType symbolType, IScriptExtent scriptExtent, string filePath = "", string sourceLine = "") + public SymbolReference( + SymbolType symbolType, + string symbolName, + IScriptExtent scriptExtent, + string filePath = "", + string sourceLine = "") { // TODO: Verify params this.SymbolType = symbolType; - this.SymbolName = scriptExtent.Text; + this.SymbolName = symbolName; this.ScriptRegion = ScriptRegion.Create(scriptExtent); this.FilePath = filePath; this.SourceLine = sourceLine; @@ -67,5 +73,17 @@ public SymbolReference(SymbolType symbolType, IScriptExtent scriptExtent, string // string.Format( // "{0} {1}") } + + /// + /// Constructs and instance of a SymbolReference + /// + /// The higher level type of the symbol + /// The script extent of the symbol + /// The file path of the symbol + /// The line contents of the given symbol (defaults to empty string) + public SymbolReference(SymbolType symbolType, IScriptExtent scriptExtent, string filePath = "", string sourceLine = "") + : this(symbolType, scriptExtent.Text, scriptExtent, filePath, sourceLine) + { + } } } diff --git a/src/PowerShellEditorServices/Symbols/PesterDocumentSymbolProvider.cs b/src/PowerShellEditorServices/Symbols/PesterDocumentSymbolProvider.cs index d249dbb9c..6eb7a2e66 100644 --- a/src/PowerShellEditorServices/Symbols/PesterDocumentSymbolProvider.cs +++ b/src/PowerShellEditorServices/Symbols/PesterDocumentSymbolProvider.cs @@ -16,6 +16,8 @@ namespace Microsoft.PowerShell.EditorServices.Symbols /// public class PesterDocumentSymbolProvider : FeatureProviderBase, IDocumentSymbolProvider { + private static char[] DefinitionTrimChars = new char[] { ' ', '{' }; + IEnumerable IDocumentSymbolProvider.ProvideDocumentSymbols( ScriptFile scriptFile) { @@ -41,11 +43,20 @@ IEnumerable IDocumentSymbolProvider.ProvideDocumentSymbols( }, true); - return commandAsts.Select(ast => new SymbolReference( - SymbolType.Function, - ast.Extent, - scriptFile.FilePath, - scriptFile.GetLine(ast.Extent.StartLineNumber))); + return commandAsts.Select( + ast => { + var testDefinitionLine = + scriptFile.GetLine( + ast.Extent.StartLineNumber); + + return + new SymbolReference( + SymbolType.Function, + testDefinitionLine.TrimEnd(DefinitionTrimChars), + ast.Extent, + scriptFile.FilePath, + testDefinitionLine); + }); } } }