Private/Invoke-Koan.ps1
function Invoke-Koan { <# .SYNOPSIS Safely invokes Pester on a koan file in a fresh scope where tests can be executed out of harm's way. .DESCRIPTION Creates a new instance of PowerShell to execute the Pester tests in. Requires a valid parameter-splat hashtable for Invoke-Pester. .PARAMETER ParameterSplat Defines the hashtable that will be splatted into Invoke-Pester in the new PowerShell instance. .EXAMPLE Invoke-Koan @{ Script = '.\AboutArrays.Koans.ps1'; PassThru = $true; Show = 'None' } Triggers Pester to assess the AboutArrays file in the current directory and pass back the complete tests object, hiding the standard test results display. #> [CmdletBinding()] [OutputType([PSObject])] param( [Parameter(Position = 0, Mandatory)] [Alias('Params')] [hashtable] $ParameterSplat ) end { try { $Requirements = [System.Management.Automation.Language.Parser]::ParseFile( $ParameterSplat.Script, [ref]$null, [ref]$null ).Ast.ScriptRequirements $Script = { param( $Params, $RequiredModules, $PSKoansPath, $PSModulePath ) [System.Collections.Generic.HashSet[string]] $ModulePaths = @( $PSModulePath -split [System.IO.Path]::PathSeparator $env:PSModulePath -split [System.IO.Path]::PathSeparator ) $env:PSModulePath = $ModulePaths -join [System.IO.Path]::PathSeparator Get-Module $PSKoansPath -ListAvailable | Import-Module foreach ($module in $RequiredModules) { Import-Module $module } Invoke-Pester @Params } $Runspace = [powershell]::Create() $Runspace.AddScript($Script) > $null $Runspace.AddParameter('Params', $ParameterSplat) > $null $Runspace.AddParameter('PSKoansPath', $MyInvocation.MyCommand.Module.ModuleBase) > $null $Runspace.AddParameter('PSModulePath', $env:PSModulePath) > $null if ($Requirements.RequiredModules) { $Runspace.AddParameter('RequiredModules', $Requirements.RequiredModules) } $Status = $Runspace.BeginInvoke() do { Start-Sleep -Milliseconds 1 } until ($Status.IsCompleted) $Result = $Runspace.EndInvoke($Status) if ($Runspace.HadErrors) { # These will be errors outside the test itself; better propagate them upwards. foreach ($errorItem in $Runspace.Streams.Error) { $PSCmdlet.WriteError($errorItem) } } $Result } finally { $Runspace.Dispose() } } } |