Skip to content
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

Add symbols for Pester setup and teardown blocks #1899

Merged
merged 3 commits into from
Aug 18, 2022
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
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,19 @@ public CodeLens[] ProvideCodeLenses(ScriptFile scriptFile, CancellationToken can
List<CodeLens> lenses = new();
foreach (SymbolReference symbol in _symbolProvider.ProvideDocumentSymbols(scriptFile))
{
cancellationToken.ThrowIfCancellationRequested();

if (symbol is not PesterSymbolReference pesterSymbol)
{
continue;
}

cancellationToken.ThrowIfCancellationRequested();
// Skip codelense for setup/teardown block
if (!PesterSymbolReference.IsPesterTestCommand(pesterSymbol.Command))
{
continue;
}

if (_configurationService.CurrentSettings.Pester.UseLegacyCodeLens
&& pesterSymbol.Command != PesterCommandType.Describe)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,33 +91,35 @@ private static PesterSymbolReference ConvertPesterAstToSymbolReference(ScriptFil
return null;
}

// Search for a name for the test
// If the test has more than one argument for names, we set it to null
string testName = null;
bool alreadySawName = false;
for (int i = 1; i < pesterCommandAst.CommandElements.Count; i++)
{
CommandElementAst currentCommandElement = pesterCommandAst.CommandElements[i];

// Check for an explicit "-Name" parameter
if (currentCommandElement is CommandParameterAst)
if (PesterSymbolReference.IsPesterTestCommand(commandName.Value)) {
// Search for a name for the test
// If the test has more than one argument for names, we set it to null
bool alreadySawName = false;
for (int i = 1; i < pesterCommandAst.CommandElements.Count; i++)
{
// Found -Name parameter, move to next element which is the argument for -TestName
i++;
CommandElementAst currentCommandElement = pesterCommandAst.CommandElements[i];

// Check for an explicit "-Name" parameter
if (currentCommandElement is CommandParameterAst)
{
// Found -Name parameter, move to next element which is the argument for -TestName
i++;

if (!alreadySawName && TryGetTestNameArgument(pesterCommandAst.CommandElements[i], out testName))
{
alreadySawName = true;
}

continue;
}

// Otherwise, if an argument is given with no parameter, we assume it's the name
// If we've already seen a name, we set the name to null
if (!alreadySawName && TryGetTestNameArgument(pesterCommandAst.CommandElements[i], out testName))
{
alreadySawName = true;
}

continue;
}

// Otherwise, if an argument is given with no parameter, we assume it's the name
// If we've already seen a name, we set the name to null
if (!alreadySawName && TryGetTestNameArgument(pesterCommandAst.CommandElements[i], out testName))
{
alreadySawName = true;
}
}

Expand Down Expand Up @@ -145,7 +147,7 @@ private static bool TryGetTestNameArgument(CommandElementAst commandElementAst,
}

/// <summary>
/// Defines command types for Pester test blocks.
/// Defines command types for Pester blocks.
/// </summary>
internal enum PesterCommandType
{
Expand All @@ -162,7 +164,32 @@ internal enum PesterCommandType
/// <summary>
/// Identifies an It block.
/// </summary>
It
It,

/// <summary>
/// Identifies an BeforeAll block.
/// </summary>
BeforeAll,

/// <summary>
/// Identifies an BeforeEach block.
/// </summary>
BeforeEach,

/// <summary>
/// Identifies an AfterAll block.
/// </summary>
AfterAll,

/// <summary>
/// Identifies an AfterEach block.
/// </summary>
AfterEach,

/// <summary>
/// Identifies an BeforeDiscovery block.
/// </summary>
BeforeDiscovery
}

/// <summary>
Expand Down Expand Up @@ -216,5 +243,18 @@ internal PesterSymbolReference(
}
return pesterCommandType;
}

/// <summary>
/// Checks if the PesterCommandType is a block with executable tests (Describe/Context/It).
/// </summary>
/// <param name="pesterCommandType">the PesterCommandType representing the Pester command</param>
/// <returns>True if command type is a block used to trigger test run. False if setup/teardown/support-block.</returns>
internal static bool IsPesterTestCommand(PesterCommandType pesterCommandType)
{
return pesterCommandType is
PesterCommandType.Describe or
PesterCommandType.Context or
PesterCommandType.It;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@ public override async Task<Container<SymbolInformation>> Handle(WorkspaceSymbolP
continue;
}

// Exclude Pester setup/teardown symbols as they're unnamed
if (foundOccurrence is PesterSymbolReference pesterSymbol &&
!PesterSymbolReference.IsPesterTestCommand(pesterSymbol.Command))
{
continue;
}

Location location = new()
{
Uri = DocumentUri.From(foundOccurrence.FilePath),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
Describe "A dummy test" {
Context "When a pester file is given" {
BeforeDiscovery {

}

BeforeAll {

}

Describe "Testing Pester symbols" {
Context "When a Pester file is given" {
BeforeAll {

}

BeforeEach {

}

It "Should return it symbols" {

}
Expand All @@ -11,5 +27,17 @@
It "Should return describe symbols" {

}

It "Should return setup and teardown symbols" {

}

AfterEach {

}
}

AfterAll {

}
}
46 changes: 38 additions & 8 deletions test/PowerShellEditorServices.Test/Language/SymbolsServiceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -315,25 +315,55 @@ public void FindsSymbolsInFile()
public void FindsSymbolsInPesterFile()
{
List<PesterSymbolReference> symbolsResult = FindSymbolsInFile(FindSymbolsInPesterFile.SourceDetails).OfType<PesterSymbolReference>().ToList();
Assert.Equal(5, symbolsResult.Count(r => r.SymbolType == SymbolType.Function));
Assert.Equal(12, symbolsResult.Count(r => r.SymbolType == SymbolType.Function));

Assert.Equal(1, symbolsResult.Count(r => r.Command == PesterCommandType.Describe));
SymbolReference firstDescribeSymbol = symbolsResult.First(r => r.Command == PesterCommandType.Describe);
Assert.Equal("Describe \"A dummy test\"", firstDescribeSymbol.SymbolName);
Assert.Equal(1, firstDescribeSymbol.ScriptRegion.StartLineNumber);
Assert.Equal("Describe \"Testing Pester symbols\"", firstDescribeSymbol.SymbolName);
Assert.Equal(9, firstDescribeSymbol.ScriptRegion.StartLineNumber);
Assert.Equal(1, firstDescribeSymbol.ScriptRegion.StartColumnNumber);

Assert.Equal(1, symbolsResult.Count(r => r.Command == PesterCommandType.Context));
SymbolReference firstContextSymbol = symbolsResult.First(r => r.Command == PesterCommandType.Context);
Assert.Equal("Context \"When a pester file is given\"", firstContextSymbol.SymbolName);
Assert.Equal(2, firstContextSymbol.ScriptRegion.StartLineNumber);
Assert.Equal("Context \"When a Pester file is given\"", firstContextSymbol.SymbolName);
Assert.Equal(10, firstContextSymbol.ScriptRegion.StartLineNumber);
Assert.Equal(5, firstContextSymbol.ScriptRegion.StartColumnNumber);

Assert.Equal(3, symbolsResult.Count(r => r.Command == PesterCommandType.It));
Assert.Equal(4, symbolsResult.Count(r => r.Command == PesterCommandType.It));
SymbolReference lastItSymbol = symbolsResult.Last(r => r.Command == PesterCommandType.It);
Assert.Equal("It \"Should return describe symbols\"", lastItSymbol.SymbolName);
Assert.Equal(11, lastItSymbol.ScriptRegion.StartLineNumber);
Assert.Equal("It \"Should return setup and teardown symbols\"", lastItSymbol.SymbolName);
Assert.Equal(31, lastItSymbol.ScriptRegion.StartLineNumber);
Assert.Equal(9, lastItSymbol.ScriptRegion.StartColumnNumber);

Assert.Equal(1, symbolsResult.Count(r => r.Command == PesterCommandType.BeforeDiscovery));
SymbolReference firstBeforeDisocverySymbol = symbolsResult.First(r => r.Command == PesterCommandType.BeforeDiscovery);
Assert.Equal("BeforeDiscovery", firstBeforeDisocverySymbol.SymbolName);
Assert.Equal(1, firstBeforeDisocverySymbol.ScriptRegion.StartLineNumber);
Assert.Equal(1, firstBeforeDisocverySymbol.ScriptRegion.StartColumnNumber);

Assert.Equal(2, symbolsResult.Count(r => r.Command == PesterCommandType.BeforeAll));
SymbolReference lastBeforeAllSymbol = symbolsResult.Last(r => r.Command == PesterCommandType.BeforeAll);
Assert.Equal("BeforeAll", lastBeforeAllSymbol.SymbolName);
Assert.Equal(11, lastBeforeAllSymbol.ScriptRegion.StartLineNumber);
Assert.Equal(9, lastBeforeAllSymbol.ScriptRegion.StartColumnNumber);

Assert.Equal(1, symbolsResult.Count(r => r.Command == PesterCommandType.BeforeEach));
SymbolReference firstBeforeEachSymbol = symbolsResult.First(r => r.Command == PesterCommandType.BeforeEach);
Assert.Equal("BeforeEach", firstBeforeEachSymbol.SymbolName);
Assert.Equal(15, firstBeforeEachSymbol.ScriptRegion.StartLineNumber);
Assert.Equal(9, firstBeforeEachSymbol.ScriptRegion.StartColumnNumber);

Assert.Equal(1, symbolsResult.Count(r => r.Command == PesterCommandType.AfterEach));
SymbolReference firstAfterEachSymbol = symbolsResult.First(r => r.Command == PesterCommandType.AfterEach);
Assert.Equal("AfterEach", firstAfterEachSymbol.SymbolName);
Assert.Equal(35, firstAfterEachSymbol.ScriptRegion.StartLineNumber);
Assert.Equal(9, firstAfterEachSymbol.ScriptRegion.StartColumnNumber);

Assert.Equal(1, symbolsResult.Count(r => r.Command == PesterCommandType.AfterAll));
SymbolReference firstAfterAllSymbol = symbolsResult.First(r => r.Command == PesterCommandType.AfterAll);
Assert.Equal("AfterAll", firstAfterAllSymbol.SymbolName);
Assert.Equal(40, firstAfterAllSymbol.ScriptRegion.StartLineNumber);
Assert.Equal(5, firstAfterAllSymbol.ScriptRegion.StartColumnNumber);
}

[Fact]
Expand Down