From eeb2240d53a4b080ed5afd922e4decd1ab959b71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Jare=C5=A1?= Date: Sun, 19 Jul 2026 12:06:23 +0200 Subject: [PATCH] Read the mock parameter filter marker directly instead of Get-Variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Test-ParameterFilter called Get-Variable -ErrorAction Ignore to save the previous value of ______isInMockParameterFilter before every filter evaluation, and Set-AssertionPassResult did the same on every passing Should-* assertion. The variable is now initialized once at module scope, so a direct $script: read works, is cheap, and is safe under strict mode, and the save/restore is a plain assignment without the conditional Remove-Variable. Also inlined Get-ConflictingParameterNames in Get-ContextToDefine (its body is the same variable read the function already does directly further down) and dropped an @() around an alias collection that already has .Count. 🤖 --- src/functions/Mock.ps1 | 20 ++++++++++--------- .../assert/Common/Set-AssertionPassResult.ps1 | 2 +- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/functions/Mock.ps1 b/src/functions/Mock.ps1 index 76a13ce1c..95d129cd2 100644 --- a/src/functions/Mock.ps1 +++ b/src/functions/Mock.ps1 @@ -1,4 +1,9 @@ +# Module-scope marker used to make Should throw (instead of recording a failure) when it runs +# inside a Mock ParameterFilter. Initialized once so the hot save/restore in Test-ParameterFilter +# and the read in Set-AssertionPassResult can access it directly instead of via Get-Variable, and +# so the direct read is safe even under Set-StrictMode. +$script:______isInMockParameterFilter = $false function New-MockBehavior { [CmdletBinding()] @@ -1339,18 +1344,13 @@ function Test-ParameterFilter { $parameterFilterInvocations = [Collections.Generic.List[string]]@() - $previousIsInMockParameterFilter = & $SafeCommands['Get-Variable'] -Name '______isInMockParameterFilter' -Scope Script -ValueOnly -ErrorAction Ignore + $previousIsInMockParameterFilter = $script:______isInMockParameterFilter $script:______isInMockParameterFilter = $true try { $result = & $wrapper $parameters } finally { - if ($null -eq $previousIsInMockParameterFilter) { - & $SafeCommands['Remove-Variable'] -Name '______isInMockParameterFilter' -Scope Script -ErrorAction Ignore - } - else { - $script:______isInMockParameterFilter = $previousIsInMockParameterFilter - } + $script:______isInMockParameterFilter = $previousIsInMockParameterFilter } $passed = [bool]$result if ($passed) { @@ -1414,7 +1414,9 @@ function Get-ContextToDefine { [System.Collections.IDictionary] $DynamicParamAliases ) - $conflictingParameterNames = Get-ConflictingParameterNames + # Inlined Get-ConflictingParameterNames (body is `$script:ConflictingParameterNames`, as already used + # directly further down in this same function) to drop a function call from this per-mock-invocation path. + $conflictingParameterNames = $script:ConflictingParameterNames $r = @{ } # key the parameters by aliases so we can resolve to # the param itself and define it and all of it's aliases @@ -1442,7 +1444,7 @@ function Get-ContextToDefine { foreach ($p in $Metadata.Parameters.GetEnumerator()) { $aliases = $p.Value.Aliases - if ($null -ne $aliases -and 0 -lt @($aliases).Count) { + if ($null -ne $aliases -and 0 -lt $aliases.Count) { foreach ($a in $aliases) { $h.Add($a, $p) } } } diff --git a/src/functions/assert/Common/Set-AssertionPassResult.ps1 b/src/functions/assert/Common/Set-AssertionPassResult.ps1 index e953971a1..c16948b77 100644 --- a/src/functions/assert/Common/Set-AssertionPassResult.ps1 +++ b/src/functions/assert/Common/Set-AssertionPassResult.ps1 @@ -1,5 +1,5 @@ function Set-AssertionPassResult { - if (& $SafeCommands['Get-Variable'] -Name '______isInMockParameterFilter' -Scope Script -ValueOnly -ErrorAction Ignore) { + if ($script:______isInMockParameterFilter) { $true } } \ No newline at end of file