You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Invoke-Pester overwrites the caller's $p and $d variables #3060
I have tested using the latest version of Pester (6.2.0, and main at 98e56d6)
What is the issue?
Invoke-Pester overwrites the caller's variables $p and $d. After the call, $p holds the path to Pester's own Pester.ScriptScope.ps1 and $d holds a hashtable with a ScriptBlock key. If the caller did not have them, they are created.
This happens in a script, in a function and at the prompt, on PowerShell 7.6 and Windows PowerShell 5.1. It goes back to Pester 5.2.0.
It can do real damage. A script that keeps a file path in $p and writes to it after running tests writes into Pester's installation instead:
$p='C:\temp\config.ps1'$orig= [IO.File]::ReadAllBytes($p)
# ... change the file, run the tests ...Invoke-Pester-Path .\config.Tests.ps1
[IO.File]::WriteAllBytes($p,$orig) # overwrites Pester.ScriptScope.ps1, not config.ps1
This happened to us. Every later Invoke-Pester run then failed all tests with no useful message, or hung waiting for input, until we restored the file from a clean copy.
Expected Behavior
Invoke-Pester does not change or create variables in the caller's scope.
Invoke-InNewScriptScope in src/Pester.Runtime.ps1 dot-sources its wrapper:
$wrapper= {
param ($private:p,$private:d)
&$private:p@d
}
# the wrapper is bound to the caller's session state.$wrapper$Path$Data
Dot-sourcing runs the wrapper in the caller's current scope, so its parameters $p and $d are bound there. private: only hides them from child scopes; it does not stop them from replacing the caller's variables.
Calling the wrapper with & instead of . fixes it. The wrapper then gets its own scope, and & $private:p still runs Pester.ScriptScope.ps1 as a script file, so the new script scope is still pushed. Invoke-File already calls its wrapper with & the same way. I will open a PR with this change and tests.
Activity