From ea2883aa76d8aeffc763f7759b6f163a5977ce53 Mon Sep 17 00:00:00 2001 From: Frode Flaten <3436158+fflaten@users.noreply.github.com> Date: Mon, 15 Aug 2022 21:38:14 +0000 Subject: [PATCH 1/3] add symbols for Pester setup and teardown blocks --- .../CodeLens/PesterCodeLensProvider.cs | 9 +- .../Symbols/PesterDocumentSymbolProvider.cs | 84 ++++++++++++++----- 2 files changed, 70 insertions(+), 23 deletions(-) diff --git a/src/PowerShellEditorServices/Services/CodeLens/PesterCodeLensProvider.cs b/src/PowerShellEditorServices/Services/CodeLens/PesterCodeLensProvider.cs index 386fb83a8..881bbc037 100644 --- a/src/PowerShellEditorServices/Services/CodeLens/PesterCodeLensProvider.cs +++ b/src/PowerShellEditorServices/Services/CodeLens/PesterCodeLensProvider.cs @@ -113,12 +113,19 @@ public CodeLens[] ProvideCodeLenses(ScriptFile scriptFile, CancellationToken can List 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) { diff --git a/src/PowerShellEditorServices/Services/Symbols/PesterDocumentSymbolProvider.cs b/src/PowerShellEditorServices/Services/Symbols/PesterDocumentSymbolProvider.cs index 59f132f1c..3c6469bc6 100644 --- a/src/PowerShellEditorServices/Services/Symbols/PesterDocumentSymbolProvider.cs +++ b/src/PowerShellEditorServices/Services/Symbols/PesterDocumentSymbolProvider.cs @@ -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; } } @@ -145,7 +147,7 @@ private static bool TryGetTestNameArgument(CommandElementAst commandElementAst, } /// - /// Defines command types for Pester test blocks. + /// Defines command types for Pester blocks. /// internal enum PesterCommandType { @@ -162,7 +164,32 @@ internal enum PesterCommandType /// /// Identifies an It block. /// - It + It, + + /// + /// Identifies an BeforeAll block. + /// + BeforeAll, + + /// + /// Identifies an BeforeEach block. + /// + BeforeEach, + + /// + /// Identifies an AfterAll block. + /// + AfterAll, + + /// + /// Identifies an AfterEach block. + /// + AfterEach, + + /// + /// Identifies an BeforeDiscovery block. + /// + BeforeDiscovery } /// @@ -216,5 +243,18 @@ internal PesterSymbolReference( } return pesterCommandType; } + + /// + /// Checks if the PesterCommandType is a block with executable tests (Describe/Context/It). + /// + /// the PesterCommandType representing the Pester command + /// True if command type is a block used to trigger test run. False if setup/teardown/support-block. + internal static bool IsPesterTestCommand(PesterCommandType pesterCommandType) + { + return pesterCommandType is + PesterCommandType.Describe or + PesterCommandType.Context or + PesterCommandType.It; + } } } From fd9393df808212b4d953b9e29e2dcf4bd863f18a Mon Sep 17 00:00:00 2001 From: Frode Flaten <3436158+fflaten@users.noreply.github.com> Date: Wed, 17 Aug 2022 14:35:22 +0000 Subject: [PATCH 2/3] update tests --- .../Symbols/PesterFile.tests.ps1 | 32 ++++++++++++- .../Language/SymbolsServiceTests.cs | 46 +++++++++++++++---- 2 files changed, 68 insertions(+), 10 deletions(-) diff --git a/test/PowerShellEditorServices.Test.Shared/Symbols/PesterFile.tests.ps1 b/test/PowerShellEditorServices.Test.Shared/Symbols/PesterFile.tests.ps1 index 086b071e0..54b291713 100644 --- a/test/PowerShellEditorServices.Test.Shared/Symbols/PesterFile.tests.ps1 +++ b/test/PowerShellEditorServices.Test.Shared/Symbols/PesterFile.tests.ps1 @@ -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" { } @@ -11,5 +27,17 @@ It "Should return describe symbols" { } + + It "Should return setup and teardown symbols" { + + } + + AfterEach { + + } + } + + AfterAll { + } } diff --git a/test/PowerShellEditorServices.Test/Language/SymbolsServiceTests.cs b/test/PowerShellEditorServices.Test/Language/SymbolsServiceTests.cs index 33fdaea0e..34f1720ce 100644 --- a/test/PowerShellEditorServices.Test/Language/SymbolsServiceTests.cs +++ b/test/PowerShellEditorServices.Test/Language/SymbolsServiceTests.cs @@ -315,25 +315,55 @@ public void FindsSymbolsInFile() public void FindsSymbolsInPesterFile() { List symbolsResult = FindSymbolsInFile(FindSymbolsInPesterFile.SourceDetails).OfType().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] From 48d196358c91072f7e2fc4db7324c93d13849428 Mon Sep 17 00:00:00 2001 From: Frode Flaten <3436158+fflaten@users.noreply.github.com> Date: Wed, 17 Aug 2022 14:48:50 +0000 Subject: [PATCH 3/3] exclude Pester setup/teardown symbols from search --- .../Services/Workspace/Handlers/WorkspaceSymbolsHandler.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/PowerShellEditorServices/Services/Workspace/Handlers/WorkspaceSymbolsHandler.cs b/src/PowerShellEditorServices/Services/Workspace/Handlers/WorkspaceSymbolsHandler.cs index 04572f431..8a9aaa815 100644 --- a/src/PowerShellEditorServices/Services/Workspace/Handlers/WorkspaceSymbolsHandler.cs +++ b/src/PowerShellEditorServices/Services/Workspace/Handlers/WorkspaceSymbolsHandler.cs @@ -56,6 +56,13 @@ public override async Task> 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),