Skip to content

Add a provider for showing run and debug CodeLenses on Pester tests #498

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 8, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion PowerShellEditorServices.build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down Expand Up @@ -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
3 changes: 3 additions & 0 deletions src/PowerShellEditorServices.Host/CodeLens/CodeLensFeature.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ public static CodeLensFeature Create(
new ReferencesCodeLensProvider(
editorSession));

codeLenses.Providers.Add(
new PesterCodeLensProvider(
editorSession));

editorSession.Components.Register<ICodeLenses>(codeLenses);

Expand Down
Original file line number Diff line number Diff line change
@@ -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<CodeLens> 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<CodeLens> ResolveCodeLensAsync(
CodeLens codeLens,
CancellationToken cancellationToken)
{
// This provider has no specific behavior for
// resolving CodeLenses.
return Task.FromResult(codeLens);
}
}
}
22 changes: 20 additions & 2 deletions src/PowerShellEditorServices/Language/SymbolReference.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,20 @@ public class SymbolReference
/// Constructs and instance of a SymbolReference
/// </summary>
/// <param name="symbolType">The higher level type of the symbol</param>
/// <param name="symbolName">The name of the symbol</param>
/// <param name="scriptExtent">The script extent of the symbol</param>
/// <param name="filePath">The file path of the symbol</param>
/// <param name="sourceLine">The line contents of the given symbol (defaults to empty string)</param>
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;
Expand All @@ -67,5 +73,17 @@ public SymbolReference(SymbolType symbolType, IScriptExtent scriptExtent, string
// string.Format(
// "{0} {1}")
}

/// <summary>
/// Constructs and instance of a SymbolReference
/// </summary>
/// <param name="symbolType">The higher level type of the symbol</param>
/// <param name="scriptExtent">The script extent of the symbol</param>
/// <param name="filePath">The file path of the symbol</param>
/// <param name="sourceLine">The line contents of the given symbol (defaults to empty string)</param>
public SymbolReference(SymbolType symbolType, IScriptExtent scriptExtent, string filePath = "", string sourceLine = "")
: this(symbolType, scriptExtent.Text, scriptExtent, filePath, sourceLine)
{
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ namespace Microsoft.PowerShell.EditorServices.Symbols
/// </summary>
public class PesterDocumentSymbolProvider : FeatureProviderBase, IDocumentSymbolProvider
{
private static char[] DefinitionTrimChars = new char[] { ' ', '{' };

IEnumerable<SymbolReference> IDocumentSymbolProvider.ProvideDocumentSymbols(
ScriptFile scriptFile)
{
Expand All @@ -41,11 +43,20 @@ IEnumerable<SymbolReference> 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);
});
}
}
}