Skip to content

Commit 17d56d9

Browse files
authored
Add symbols for Pester setup and teardown blocks (#1899)
* add symbols for Pester setup and teardown blocks * update tests * exclude Pester setup/teardown symbols from search
1 parent 0b96dae commit 17d56d9

File tree

5 files changed

+145
-33
lines changed

5 files changed

+145
-33
lines changed

src/PowerShellEditorServices/Services/CodeLens/PesterCodeLensProvider.cs

+8-1
Original file line numberDiff line numberDiff line change
@@ -113,12 +113,19 @@ public CodeLens[] ProvideCodeLenses(ScriptFile scriptFile, CancellationToken can
113113
List<CodeLens> lenses = new();
114114
foreach (SymbolReference symbol in _symbolProvider.ProvideDocumentSymbols(scriptFile))
115115
{
116+
cancellationToken.ThrowIfCancellationRequested();
117+
116118
if (symbol is not PesterSymbolReference pesterSymbol)
117119
{
118120
continue;
119121
}
120122

121-
cancellationToken.ThrowIfCancellationRequested();
123+
// Skip codelense for setup/teardown block
124+
if (!PesterSymbolReference.IsPesterTestCommand(pesterSymbol.Command))
125+
{
126+
continue;
127+
}
128+
122129
if (_configurationService.CurrentSettings.Pester.UseLegacyCodeLens
123130
&& pesterSymbol.Command != PesterCommandType.Describe)
124131
{

src/PowerShellEditorServices/Services/Symbols/PesterDocumentSymbolProvider.cs

+62-22
Original file line numberDiff line numberDiff line change
@@ -91,33 +91,35 @@ private static PesterSymbolReference ConvertPesterAstToSymbolReference(ScriptFil
9191
return null;
9292
}
9393

94-
// Search for a name for the test
95-
// If the test has more than one argument for names, we set it to null
9694
string testName = null;
97-
bool alreadySawName = false;
98-
for (int i = 1; i < pesterCommandAst.CommandElements.Count; i++)
99-
{
100-
CommandElementAst currentCommandElement = pesterCommandAst.CommandElements[i];
101-
102-
// Check for an explicit "-Name" parameter
103-
if (currentCommandElement is CommandParameterAst)
95+
if (PesterSymbolReference.IsPesterTestCommand(commandName.Value)) {
96+
// Search for a name for the test
97+
// If the test has more than one argument for names, we set it to null
98+
bool alreadySawName = false;
99+
for (int i = 1; i < pesterCommandAst.CommandElements.Count; i++)
104100
{
105-
// Found -Name parameter, move to next element which is the argument for -TestName
106-
i++;
101+
CommandElementAst currentCommandElement = pesterCommandAst.CommandElements[i];
102+
103+
// Check for an explicit "-Name" parameter
104+
if (currentCommandElement is CommandParameterAst)
105+
{
106+
// Found -Name parameter, move to next element which is the argument for -TestName
107+
i++;
107108

109+
if (!alreadySawName && TryGetTestNameArgument(pesterCommandAst.CommandElements[i], out testName))
110+
{
111+
alreadySawName = true;
112+
}
113+
114+
continue;
115+
}
116+
117+
// Otherwise, if an argument is given with no parameter, we assume it's the name
118+
// If we've already seen a name, we set the name to null
108119
if (!alreadySawName && TryGetTestNameArgument(pesterCommandAst.CommandElements[i], out testName))
109120
{
110121
alreadySawName = true;
111122
}
112-
113-
continue;
114-
}
115-
116-
// Otherwise, if an argument is given with no parameter, we assume it's the name
117-
// If we've already seen a name, we set the name to null
118-
if (!alreadySawName && TryGetTestNameArgument(pesterCommandAst.CommandElements[i], out testName))
119-
{
120-
alreadySawName = true;
121123
}
122124
}
123125

@@ -145,7 +147,7 @@ private static bool TryGetTestNameArgument(CommandElementAst commandElementAst,
145147
}
146148

147149
/// <summary>
148-
/// Defines command types for Pester test blocks.
150+
/// Defines command types for Pester blocks.
149151
/// </summary>
150152
internal enum PesterCommandType
151153
{
@@ -162,7 +164,32 @@ internal enum PesterCommandType
162164
/// <summary>
163165
/// Identifies an It block.
164166
/// </summary>
165-
It
167+
It,
168+
169+
/// <summary>
170+
/// Identifies an BeforeAll block.
171+
/// </summary>
172+
BeforeAll,
173+
174+
/// <summary>
175+
/// Identifies an BeforeEach block.
176+
/// </summary>
177+
BeforeEach,
178+
179+
/// <summary>
180+
/// Identifies an AfterAll block.
181+
/// </summary>
182+
AfterAll,
183+
184+
/// <summary>
185+
/// Identifies an AfterEach block.
186+
/// </summary>
187+
AfterEach,
188+
189+
/// <summary>
190+
/// Identifies an BeforeDiscovery block.
191+
/// </summary>
192+
BeforeDiscovery
166193
}
167194

168195
/// <summary>
@@ -216,5 +243,18 @@ internal PesterSymbolReference(
216243
}
217244
return pesterCommandType;
218245
}
246+
247+
/// <summary>
248+
/// Checks if the PesterCommandType is a block with executable tests (Describe/Context/It).
249+
/// </summary>
250+
/// <param name="pesterCommandType">the PesterCommandType representing the Pester command</param>
251+
/// <returns>True if command type is a block used to trigger test run. False if setup/teardown/support-block.</returns>
252+
internal static bool IsPesterTestCommand(PesterCommandType pesterCommandType)
253+
{
254+
return pesterCommandType is
255+
PesterCommandType.Describe or
256+
PesterCommandType.Context or
257+
PesterCommandType.It;
258+
}
219259
}
220260
}

src/PowerShellEditorServices/Services/Workspace/Handlers/WorkspaceSymbolsHandler.cs

+7
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,13 @@ public override async Task<Container<SymbolInformation>> Handle(WorkspaceSymbolP
5656
continue;
5757
}
5858

59+
// Exclude Pester setup/teardown symbols as they're unnamed
60+
if (foundOccurrence is PesterSymbolReference pesterSymbol &&
61+
!PesterSymbolReference.IsPesterTestCommand(pesterSymbol.Command))
62+
{
63+
continue;
64+
}
65+
5966
Location location = new()
6067
{
6168
Uri = DocumentUri.From(foundOccurrence.FilePath),

test/PowerShellEditorServices.Test.Shared/Symbols/PesterFile.tests.ps1

+30-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,21 @@
1-
Describe "A dummy test" {
2-
Context "When a pester file is given" {
1+
BeforeDiscovery {
2+
3+
}
4+
5+
BeforeAll {
6+
7+
}
8+
9+
Describe "Testing Pester symbols" {
10+
Context "When a Pester file is given" {
11+
BeforeAll {
12+
13+
}
14+
15+
BeforeEach {
16+
17+
}
18+
319
It "Should return it symbols" {
420

521
}
@@ -11,5 +27,17 @@
1127
It "Should return describe symbols" {
1228

1329
}
30+
31+
It "Should return setup and teardown symbols" {
32+
33+
}
34+
35+
AfterEach {
36+
37+
}
38+
}
39+
40+
AfterAll {
41+
1442
}
1543
}

test/PowerShellEditorServices.Test/Language/SymbolsServiceTests.cs

+38-8
Original file line numberDiff line numberDiff line change
@@ -315,25 +315,55 @@ public void FindsSymbolsInFile()
315315
public void FindsSymbolsInPesterFile()
316316
{
317317
List<PesterSymbolReference> symbolsResult = FindSymbolsInFile(FindSymbolsInPesterFile.SourceDetails).OfType<PesterSymbolReference>().ToList();
318-
Assert.Equal(5, symbolsResult.Count(r => r.SymbolType == SymbolType.Function));
318+
Assert.Equal(12, symbolsResult.Count(r => r.SymbolType == SymbolType.Function));
319319

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

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

332-
Assert.Equal(3, symbolsResult.Count(r => r.Command == PesterCommandType.It));
332+
Assert.Equal(4, symbolsResult.Count(r => r.Command == PesterCommandType.It));
333333
SymbolReference lastItSymbol = symbolsResult.Last(r => r.Command == PesterCommandType.It);
334-
Assert.Equal("It \"Should return describe symbols\"", lastItSymbol.SymbolName);
335-
Assert.Equal(11, lastItSymbol.ScriptRegion.StartLineNumber);
334+
Assert.Equal("It \"Should return setup and teardown symbols\"", lastItSymbol.SymbolName);
335+
Assert.Equal(31, lastItSymbol.ScriptRegion.StartLineNumber);
336336
Assert.Equal(9, lastItSymbol.ScriptRegion.StartColumnNumber);
337+
338+
Assert.Equal(1, symbolsResult.Count(r => r.Command == PesterCommandType.BeforeDiscovery));
339+
SymbolReference firstBeforeDisocverySymbol = symbolsResult.First(r => r.Command == PesterCommandType.BeforeDiscovery);
340+
Assert.Equal("BeforeDiscovery", firstBeforeDisocverySymbol.SymbolName);
341+
Assert.Equal(1, firstBeforeDisocverySymbol.ScriptRegion.StartLineNumber);
342+
Assert.Equal(1, firstBeforeDisocverySymbol.ScriptRegion.StartColumnNumber);
343+
344+
Assert.Equal(2, symbolsResult.Count(r => r.Command == PesterCommandType.BeforeAll));
345+
SymbolReference lastBeforeAllSymbol = symbolsResult.Last(r => r.Command == PesterCommandType.BeforeAll);
346+
Assert.Equal("BeforeAll", lastBeforeAllSymbol.SymbolName);
347+
Assert.Equal(11, lastBeforeAllSymbol.ScriptRegion.StartLineNumber);
348+
Assert.Equal(9, lastBeforeAllSymbol.ScriptRegion.StartColumnNumber);
349+
350+
Assert.Equal(1, symbolsResult.Count(r => r.Command == PesterCommandType.BeforeEach));
351+
SymbolReference firstBeforeEachSymbol = symbolsResult.First(r => r.Command == PesterCommandType.BeforeEach);
352+
Assert.Equal("BeforeEach", firstBeforeEachSymbol.SymbolName);
353+
Assert.Equal(15, firstBeforeEachSymbol.ScriptRegion.StartLineNumber);
354+
Assert.Equal(9, firstBeforeEachSymbol.ScriptRegion.StartColumnNumber);
355+
356+
Assert.Equal(1, symbolsResult.Count(r => r.Command == PesterCommandType.AfterEach));
357+
SymbolReference firstAfterEachSymbol = symbolsResult.First(r => r.Command == PesterCommandType.AfterEach);
358+
Assert.Equal("AfterEach", firstAfterEachSymbol.SymbolName);
359+
Assert.Equal(35, firstAfterEachSymbol.ScriptRegion.StartLineNumber);
360+
Assert.Equal(9, firstAfterEachSymbol.ScriptRegion.StartColumnNumber);
361+
362+
Assert.Equal(1, symbolsResult.Count(r => r.Command == PesterCommandType.AfterAll));
363+
SymbolReference firstAfterAllSymbol = symbolsResult.First(r => r.Command == PesterCommandType.AfterAll);
364+
Assert.Equal("AfterAll", firstAfterAllSymbol.SymbolName);
365+
Assert.Equal(40, firstAfterAllSymbol.ScriptRegion.StartLineNumber);
366+
Assert.Equal(5, firstAfterAllSymbol.ScriptRegion.StartColumnNumber);
337367
}
338368

339369
[Fact]

0 commit comments

Comments
 (0)