From 74b2f27d8450b14105cc56212a6cd82c3fcf9781 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Jare=C5=A1?= Date: Thu, 13 Jun 2024 23:08:19 +0200 Subject: [PATCH 1/6] Add option to disable v5 syntax --- src/Pester.RSpec.ps1 | 3 ++ src/csharp/Pester/ShouldConfiguration.cs | 19 +++++++++ src/functions/assertions/Should.ps1 | 21 ++++++---- tst/Pester.RSpec.Configuration.ts.ps1 | 49 +++++++++++++++++++++--- 4 files changed, 79 insertions(+), 13 deletions(-) diff --git a/src/Pester.RSpec.ps1 b/src/Pester.RSpec.ps1 index bf83c9d18..f21f1a0b8 100644 --- a/src/Pester.RSpec.ps1 +++ b/src/Pester.RSpec.ps1 @@ -389,6 +389,9 @@ function New-PesterConfiguration { ErrorAction: Controls if Should throws on error. Use 'Stop' to throw on error, or 'Continue' to fail at the end of the test. Default value: 'Stop' + DisableV5: Disables usage of Should -Be assertions, that are replaced by Should-Be in version 6. + Default value: $false + Debug: ShowFullErrors: Show full errors including Pester internal stack. This property is deprecated, and if set to true it will override Output.StackTraceVerbosity to 'Full'. Default value: $false diff --git a/src/csharp/Pester/ShouldConfiguration.cs b/src/csharp/Pester/ShouldConfiguration.cs index 551df69c4..bd658190f 100644 --- a/src/csharp/Pester/ShouldConfiguration.cs +++ b/src/csharp/Pester/ShouldConfiguration.cs @@ -22,6 +22,7 @@ namespace Pester public class ShouldConfiguration : ConfigurationSection { private StringOption _errorAction; + private BoolOption _disableV5; public static ShouldConfiguration Default { get { return new ShouldConfiguration(); } } @@ -33,11 +34,13 @@ public static ShouldConfiguration ShallowClone(ShouldConfiguration configuration public ShouldConfiguration() : base("Should configuration.") { ErrorAction = new StringOption("Controls if Should throws on error. Use 'Stop' to throw on error, or 'Continue' to fail at the end of the test.", "Stop"); + DisableV5 = new BoolOption("Disables usage of Should -Be assertions, that are replaced by Should-Be in version 6.", false); } public ShouldConfiguration(IDictionary configuration) : this() { configuration?.AssignObjectIfNotNull(nameof(ErrorAction), v => ErrorAction = v); + configuration?.AssignValueIfNotNull(nameof(DisableV5), v => DisableV5 = v); } public StringOption ErrorAction @@ -55,5 +58,21 @@ public StringOption ErrorAction } } } + + public BoolOption DisableV5 + { + get { return _disableV5; } + set + { + if (_disableV5 == null) + { + _disableV5 = value; + } + else + { + _disableV5 = new BoolOption(_disableV5, value.Value); + } + } + } } } diff --git a/src/functions/assertions/Should.ps1 b/src/functions/assertions/Should.ps1 index c130e6a64..2a7074212 100644 --- a/src/functions/assertions/Should.ps1 +++ b/src/functions/assertions/Should.ps1 @@ -122,18 +122,23 @@ function Should { $shouldThrow = 'Stop' -eq $PSBoundParameters["ErrorAction"] } + # first check if we are in the context of Pester, if not we will always throw, and won't disable Should: + # This check is slightly hacky, here we are reaching out the the caller session state and + # look for $______parameters which we know we are using inside of the Pester runtime to + # keep the current invocation context, when we find it, we are able to add non-terminating + # errors without throwing and terminating the test. + $pesterRuntimeInvocationContext = $PSCmdlet.SessionState.PSVariable.GetValue('______parameters') + $isInsidePesterRuntime = $null -ne $pesterRuntimeInvocationContext + $pesterRuntimeInvocationContext.Configuration.Should.ErrorAction.Value + + if ($isInsidePesterRuntime -and $pesterRuntimeInvocationContext.Configuration.Should.DisableV5.Value) { + throw "Pester Should -Be syntax is disabled. Use Should-Be (without space), or enable it by setting: `$PesterPreference.Should.DisableV5 = `$false" + } + if ($null -eq $shouldThrow -or -not $shouldThrow) { # we are sure that we either: # - should not throw because of explicit ErrorAction, and need to figure out a place where to collect the error # - or we don't know what to do yet and need to figure out what to do based on the context and settings - - # first check if we are in the context of Pester, if not we will always throw: - # this is slightly hacky, here we are reaching out the the caller session state and - # look for $______parameters which we know we are using inside of the Pester runtime to - # keep the current invocation context, when we find it, we are able to add non-terminating - # errors without throwing and terminating the test - $pesterRuntimeInvocationContext = $PSCmdlet.SessionState.PSVariable.GetValue('______parameters') - $isInsidePesterRuntime = $null -ne $pesterRuntimeInvocationContext if (-not $isInsidePesterRuntime) { $shouldThrow = $true } diff --git a/tst/Pester.RSpec.Configuration.ts.ps1 b/tst/Pester.RSpec.Configuration.ts.ps1 index 7dc00b467..0fafc1d5d 100644 --- a/tst/Pester.RSpec.Configuration.ts.ps1 +++ b/tst/Pester.RSpec.Configuration.ts.ps1 @@ -135,6 +135,10 @@ i -PassThru:$PassThru { [PesterConfiguration]::Default.Should.ErrorAction.Value | Verify-Equal 'Stop' } + t "Should.DisableV5 is `$false" { + [PesterConfiguration]::Default.Should.DisableV5.Value | Verify-Equal $false + } + # Debug configuration t "Debug.ShowFullErrors is `$false" { [PesterConfiguration]::Default.Debug.ShowFullErrors.Value | Verify-False @@ -1140,7 +1144,7 @@ i -PassThru:$PassThru { Throw = $true } Output = @{ - CIFormat = 'None' + CIFormat = 'None' CILogLevel = 'Something' } } @@ -1152,7 +1156,7 @@ i -PassThru:$PassThru { b 'Output.RenderMode' { t 'Output.RenderMode is Plaintext when set to Auto (default) and env:NO_COLOR is set' { $c = [PesterConfiguration] @{ - Run = @{ + Run = @{ ScriptBlock = { } PassThru = $true } @@ -1225,7 +1229,7 @@ i -PassThru:$PassThru { $pesterPath = Get-Module Pester | Select-Object -ExpandProperty Path try { $ps = [PowerShell]::Create() - $ps.AddCommand('Set-StrictMode').AddParameter('Version','Latest') > $null + $ps.AddCommand('Set-StrictMode').AddParameter('Version', 'Latest') > $null $ps.AddStatement().AddScript("Import-Module '$pesterPath' -Force") > $null $ps.AddStatement().AddScript('$c = [PesterConfiguration]@{Run = @{ScriptBlock={ describe "d1" { it "i1" { } } };PassThru=$true};Output=@{RenderMode="Auto"}}') > $null $ps.AddStatement().AddScript('Invoke-Pester -Configuration $c') > $null @@ -1243,7 +1247,7 @@ i -PassThru:$PassThru { t 'Each non-Auto option can be set and updated' { $c = [PesterConfiguration] @{ - Run = @{ + Run = @{ ScriptBlock = { } PassThru = $true } @@ -1277,7 +1281,8 @@ i -PassThru:$PassThru { try { Invoke-Pester -Configuration $c $true | Verify-False # Should not get here - } catch { + } + catch { $_.Exception.Message -match "Output.RenderMode must be .* it was 'Something'" | Verify-True $failed = $true } @@ -1323,4 +1328,38 @@ i -PassThru:$PassThru { { Invoke-Pester -Configuration $c } | Verify-Throw } } + + b "Should.DisableV5" { + t "Disabling V5 assertions makes Should -Be throw" { + $c = [PesterConfiguration]@{ + Run = @{ + ScriptBlock = { Describe 'a' { It 'b' { 1 | Should -Be 1 } } } + PassThru = $true + } + Should = @{ + DisableV5 = $true + } + } + + $r = Invoke-Pester -Configuration $c + $err = $r.Containers.Blocks.Tests.ErrorRecord + + $err | Verify-Equal 'Pester Should -Be syntax is disabled. Use Should-Be (without space), or enable it by setting: $PesterPreference.Should.DisableV5 = $false' + } + + t "Enabling V5 assertions makes Should -Be pass" { + $c = [PesterConfiguration]@{ + Run = @{ + ScriptBlock = { Describe 'a' { It 'b' { 1 | Should -Be 1 } } } + PassThru = $true + } + Should = @{ + DisableV5 = $false + } + } + + $r = Invoke-Pester -Configuration $c + $r.Result | Verify-Equal "Passed" + } + } } From bbdf0a38d617e316f772606ff9e7143e91fe40fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Jare=C5=A1?= Date: Thu, 13 Jun 2024 23:24:29 +0200 Subject: [PATCH 2/6] Remove extra output --- src/functions/assertions/Should.ps1 | 1 - 1 file changed, 1 deletion(-) diff --git a/src/functions/assertions/Should.ps1 b/src/functions/assertions/Should.ps1 index 2a7074212..72f32d096 100644 --- a/src/functions/assertions/Should.ps1 +++ b/src/functions/assertions/Should.ps1 @@ -129,7 +129,6 @@ function Should { # errors without throwing and terminating the test. $pesterRuntimeInvocationContext = $PSCmdlet.SessionState.PSVariable.GetValue('______parameters') $isInsidePesterRuntime = $null -ne $pesterRuntimeInvocationContext - $pesterRuntimeInvocationContext.Configuration.Should.ErrorAction.Value if ($isInsidePesterRuntime -and $pesterRuntimeInvocationContext.Configuration.Should.DisableV5.Value) { throw "Pester Should -Be syntax is disabled. Use Should-Be (without space), or enable it by setting: `$PesterPreference.Should.DisableV5 = `$false" From c1063d05ebbd73f2501b11e179216325c60a1d75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Jare=C5=A1?= Date: Thu, 13 Jun 2024 23:28:29 +0200 Subject: [PATCH 3/6] Update src/functions/assertions/Should.ps1 Co-authored-by: Frode Flaten <3436158+fflaten@users.noreply.github.com> --- src/functions/assertions/Should.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/functions/assertions/Should.ps1 b/src/functions/assertions/Should.ps1 index 72f32d096..fc0130d4d 100644 --- a/src/functions/assertions/Should.ps1 +++ b/src/functions/assertions/Should.ps1 @@ -123,7 +123,7 @@ function Should { } # first check if we are in the context of Pester, if not we will always throw, and won't disable Should: - # This check is slightly hacky, here we are reaching out the the caller session state and + # This check is slightly hacky, here we are reaching out the caller session state and # look for $______parameters which we know we are using inside of the Pester runtime to # keep the current invocation context, when we find it, we are able to add non-terminating # errors without throwing and terminating the test. From e9433a090e7ea699ed3eadb46763cfc6a9af0c52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Jare=C5=A1?= Date: Thu, 13 Jun 2024 23:41:17 +0200 Subject: [PATCH 4/6] Check message, so we don't write error to pipeline --- tst/Pester.RSpec.Configuration.ts.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tst/Pester.RSpec.Configuration.ts.ps1 b/tst/Pester.RSpec.Configuration.ts.ps1 index 0fafc1d5d..ce701fc70 100644 --- a/tst/Pester.RSpec.Configuration.ts.ps1 +++ b/tst/Pester.RSpec.Configuration.ts.ps1 @@ -1344,7 +1344,7 @@ i -PassThru:$PassThru { $r = Invoke-Pester -Configuration $c $err = $r.Containers.Blocks.Tests.ErrorRecord - $err | Verify-Equal 'Pester Should -Be syntax is disabled. Use Should-Be (without space), or enable it by setting: $PesterPreference.Should.DisableV5 = $false' + $err.Message | Verify-Equal 'Pester Should -Be syntax is disabled. Use Should-Be (without space), or enable it by setting: $PesterPreference.Should.DisableV5 = $false' } t "Enabling V5 assertions makes Should -Be pass" { From 3e059629fba2af3d7be36ae9172ba611bc4947b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Jare=C5=A1?= Date: Thu, 13 Jun 2024 23:49:02 +0200 Subject: [PATCH 5/6] Check message, so we don't write error to pipeline --- tst/Pester.RSpec.Configuration.ts.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tst/Pester.RSpec.Configuration.ts.ps1 b/tst/Pester.RSpec.Configuration.ts.ps1 index ce701fc70..607d17bce 100644 --- a/tst/Pester.RSpec.Configuration.ts.ps1 +++ b/tst/Pester.RSpec.Configuration.ts.ps1 @@ -1344,7 +1344,7 @@ i -PassThru:$PassThru { $r = Invoke-Pester -Configuration $c $err = $r.Containers.Blocks.Tests.ErrorRecord - $err.Message | Verify-Equal 'Pester Should -Be syntax is disabled. Use Should-Be (without space), or enable it by setting: $PesterPreference.Should.DisableV5 = $false' + $err.Exception.Message | Verify-Equal 'Pester Should -Be syntax is disabled. Use Should-Be (without space), or enable it by setting: $PesterPreference.Should.DisableV5 = $false' } t "Enabling V5 assertions makes Should -Be pass" { From 2e25cce68e78b6dff67eae049be04221ec419c3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Jare=C5=A1?= Date: Fri, 14 Jun 2024 00:01:25 +0200 Subject: [PATCH 6/6] Don't format my error --- tst/Pester.RSpec.Configuration.ts.ps1 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tst/Pester.RSpec.Configuration.ts.ps1 b/tst/Pester.RSpec.Configuration.ts.ps1 index 607d17bce..1447fd98d 100644 --- a/tst/Pester.RSpec.Configuration.ts.ps1 +++ b/tst/Pester.RSpec.Configuration.ts.ps1 @@ -1339,6 +1339,9 @@ i -PassThru:$PassThru { Should = @{ DisableV5 = $true } + Output = @{ + CIFormat = 'None' + } } $r = Invoke-Pester -Configuration $c