Skip to content

Commit

Permalink
Merge pull request pester#206 from dlwyatt/DynamicParamFix
Browse files Browse the repository at this point in the history
Mocking fix
  • Loading branch information
dlwyatt committed Sep 3, 2014
2 parents 603f012 + dc64ab1 commit 3051aba
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 39 deletions.
18 changes: 18 additions & 0 deletions Functions/Mock.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -819,6 +819,8 @@ Describe 'Mocking functions with dynamic parameters in a module' {
New-Module -Name TestModule {
function PublicFunction { Get-Greeting -Name lowercase -Capitalize }

$script:DoDynamicParam = $true

# Get-Greeting sample function borrowed and modified from Bartek Bielawski's
# blog at http://becomelotr.wordpress.com/2012/05/10/using-and-abusing-dynamic-parameters/

Expand All @@ -829,6 +831,10 @@ Describe 'Mocking functions with dynamic parameters in a module' {
)

DynamicParam {
# This check is here to make sure the mocked version can still work if the
# original function's dynamicparam block relied on script-scope variables.
if (-not $script:DoDynamicParam) { return }

if ($Name -cmatch '\b[a-z]') {
$Attributes = New-Object Management.Automation.ParameterAttribute
$Attributes.ParameterSetName = "__AllParameterSets"
Expand Down Expand Up @@ -870,3 +876,15 @@ Describe 'Mocking functions with dynamic parameters in a module' {

Remove-Module TestModule -Force
}

Describe 'Parameter Filters and Common Parameters' {
function Test-Function { [CmdletBinding()] param ( ) }

Mock Test-Function { } -ParameterFilter { $VerbosePreference -eq 'Continue' }

It 'Applies common parameters correctly when testing the parameter filter' {
{ Test-Function -Verbose } | Should Not Throw
Assert-MockCalled Test-Function
Assert-MockCalled Test-Function -ParameterFilter { $VerbosePreference -eq 'Continue' }
}
}
105 changes: 66 additions & 39 deletions Functions/Mock.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ about_Mocking

if (-not $mock)
{
$metadata = $null
$cmdletBinding = ''
$paramBlock = ''
$dynamicParamBlock = ''
Expand Down Expand Up @@ -230,12 +231,10 @@ about_Mocking
$mock = @{
OriginalCommand = $contextInfo.Command
Blocks = @()
Cmdlet = $cmdletBinding
Params = $paramBlock
DynamicParams = $dynamicParamBlock
CommandName = $CommandName
SessionState = $contextInfo.Session
Scope = $pester.Scope
Metadata = $metadata
CallHistory = @()
}

Expand Down Expand Up @@ -480,18 +479,14 @@ param(
}
}

$cmd = [scriptblock]::Create("$($mock.CmdLet) `r`n param ( $($mock.Params) ) `r`n$parameterFilter")

$qualifiedCalls = @(
$mock.CallHistory |
Where-Object {
$params = @{
ScriptBlock = $ParameterFilter
BoundParameters = $_.BoundParams
ArgumentList = $_.Args
CmdletBinding = $mock.Cmdlet
ParamBlock = $mock.Params
DynamicParamBlock = $mock.DynamicParams
ScriptBlock = $ParameterFilter
BoundParameters = $_.BoundParams
ArgumentList = $_.Args
Metadata = $mock.Metadata
}

(Test-MockCallScope -CallScope $_.Scope -DesiredScope $Scope) -and (Test-ParameterFilter @params)
Expand Down Expand Up @@ -631,12 +626,10 @@ function Invoke-Mock {
$block = $mock.Blocks[$idx - 1]

$params = @{
ScriptBlock = $block.Filter
BoundParameters = $BoundParameters
ArgumentList = $ArgumentList
CmdletBinding = $mock.Cmdlet
ParamBlock = $mock.Params
DynamicParamBlock = $mock.DynamicParams
ScriptBlock = $block.Filter
BoundParameters = $BoundParameters
ArgumentList = $ArgumentList
Metadata = $mock.Metadata
}

if (Test-ParameterFilter @params)
Expand Down Expand Up @@ -734,35 +727,20 @@ function Test-ParameterFilter
[object[]]
$ArgumentList,

[string]
$CmdletBinding,

[string]
$ParamBlock,

[string]
$DynamicParamBlock
[System.Management.Automation.CommandMetadata]
$Metadata
)

if ($null -eq $BoundParameters) { $BoundParameters = @{} }
if ($null -eq $ArgumentList) { $ArgumentList = @() }
if ($null -eq $CmdletBinding) { $CmdletBinding = '' }
if ($null -eq $ParamBlock) { $ParamBlock = '' }
if ($null -eq $DynamicParamBlock) { $DynamicParamBlock = '' }

$scriptBlockString = "
$CmdletBinding
param (
$ParamBlock
)
$paramBlock = Get-ParamBlockFromBoundParameters -BoundParameters $BoundParameters -Metadata $Metadata

$DynamicParamBlock
$scriptBlockString = "
$paramBlock
end {
Set-StrictMode -Off
Set-DynamicParameterVariables -SessionState `$ExecutionContext.SessionState -Parameters `$PSBoundParameters
$ScriptBlock
}
Set-StrictMode -Off
$ScriptBlock
"

$cmd = [scriptblock]::Create($scriptBlockString)
Expand All @@ -771,6 +749,55 @@ function Test-ParameterFilter
& $cmd @BoundParameters @ArgumentList
}

function Get-ParamBlockFromBoundParameters
{
param (
[System.Collections.IDictionary] $BoundParameters,
[System.Management.Automation.CommandMetadata] $Metadata
)

$params = foreach ($paramName in $BoundParameters.Keys)
{
if ($null -ne $Metadata -and (IsCommonParameter -Name $paramName -Metadata $Metadata))
{
continue
}

"`${$paramName}"
}

$params = $params -join ','

if ($null -ne $Metadata)
{
$cmdletBinding = [System.Management.Automation.ProxyCommand]::GetCmdletBindingAttribute($Metadata)
}
else
{
$cmdletBinding = ''
}

return "$cmdletBinding param ($params)"
}

function IsCommonParameter
{
param (
[string] $Name,
[System.Management.Automation.CommandMetadata] $Metadata
)

if ($null -ne $Metadata)
{
if ([System.Management.Automation.Internal.CommonParameters].GetProperty($Name)) { return $true }
if ($Metadata.SupportsShouldProcess -and [System.Management.Automation.Internal.ShouldProcessParameters].GetProperty($Name)) { return $true }
if ($Metadata.SupportsPaging -and [System.Management.Automation.PagingParameters].GetProperty($Name)) { return $true }
if ($Metadata.SupportsTransactions -and [System.Management.Automation.Internal.TransactionParameters].GetProperty($Name)) { return $true }
}

return $false
}

function Get-ScopeForMock
{
param ($PesterState)
Expand Down

0 comments on commit 3051aba

Please sign in to comment.