Skip to content

Commit

Permalink
Add -InParameterSet in Should -HaveParameter (#2273)
Browse files Browse the repository at this point in the history
  • Loading branch information
fflaten committed May 6, 2023
1 parent d318bdd commit 08998af
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 12 deletions.
38 changes: 28 additions & 10 deletions src/functions/assertions/HaveParameter.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
$ActualValue,
[String] $ParameterName,
$Type,
[String]$DefaultValue,
[Switch]$Mandatory,
[Switch]$HasArgumentCompleter,
[String[]]$Alias,
[Switch]$Negate,
[String]$Because ) {
[String] $DefaultValue,
[Switch] $Mandatory,
[String] $InParameterSet,
[Switch] $HasArgumentCompleter,
[String[]] $Alias,
[Switch] $Negate,
[String] $Because ) {
<#
.SYNOPSIS
Asserts that a command has the expected parameter.
Expand All @@ -30,6 +31,7 @@
throw "The ParameterName can't be empty"
}

#region HelperFunctions
function Get-ParameterInfo {
param (
[Parameter(Mandatory = $true)]
Expand Down Expand Up @@ -149,6 +151,7 @@
}
}
}
#endregion HelperFunctions

if ($Type -is [string]) {
# parses type that is provided as a string in brackets (such as [int])
Expand All @@ -160,7 +163,6 @@

$Type = $parsedType
}
#endregion HelperFunctions

$buts = @()
$filters = @()
Expand All @@ -181,22 +183,38 @@
}

$hasKey = $ActualValue.Parameters.PSBase.ContainsKey($ParameterName)
$filters += "to$(if ($Negate) {" not"}) have a parameter $ParameterName"
$filters += "to$(if ($Negate) {' not'}) have a parameter $ParameterName$(if ($InParameterSet) { " in parameter set $InParameterSet" })"

if (-not $Negate -and -not $hasKey) {
$buts += "the parameter is missing"
}
elseif ($Negate -and -not $hasKey) {
return & $SafeCommands['New-Object'] PSObject -Property @{ Succeeded = $true }
}
elseif ($Negate -and $hasKey -and -not ($Mandatory -or $Type -or $DefaultValue -or $HasArgumentCompleter)) {
elseif ($Negate -and $hasKey -and -not ($InParameterSet -or $Mandatory -or $Type -or $DefaultValue -or $HasArgumentCompleter)) {
$buts += "the parameter exists"
}
else {
$attributes = $ActualValue.Parameters[$ParameterName].Attributes
$parameterAttributes = $attributes | & $SafeCommands['Where-Object'] { $_ -is [System.Management.Automation.ParameterAttribute] }

if ($InParameterSet) {
$parameterAttributes = $parameterAttributes | & $SafeCommands['Where-Object'] { $_.ParameterSetName -eq $InParameterSet }

if (-not $Negate -and -not $parameterAttributes) {
$buts += 'the parameter is missing'
}
elseif ($Negate -and $parameterAttributes) {
$buts += 'the parameter exists'
}
}
}

if ($buts.Count -eq 0) {
# Parameter exists (in set if specified), assert remaining requirements

if ($Mandatory) {
$testMandatory = $attributes | & $SafeCommands['Where-Object'] { $_ -is [System.Management.Automation.ParameterAttribute] -and $_.Mandatory }
$testMandatory = $parameterAttributes | & $SafeCommands['Where-Object'] { $_.Mandatory }
$filters += "which is$(if ($Negate) {" not"}) mandatory"

if (-not $Negate -and -not $testMandatory) {
Expand Down
57 changes: 55 additions & 2 deletions tst/functions/assertions/HaveParameter.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ InPesterModuleScope {
if ($PSVersionTable.PSVersion.Major -ge 5) {
function Invoke-DummyFunction {
param(
[Parameter(Mandatory = $true)]
[Parameter(Mandatory = $true, ParameterSetName = 'PrimarySet')]
[Alias('First', 'Another')]
$MandatoryParam,

[Parameter(ParameterSetName = 'PrimarySet')]
[ValidateNotNullOrEmpty()]
[DateTime]$ParamWithNotNullOrEmptyValidation = (Get-Date),

Expand Down Expand Up @@ -62,10 +63,11 @@ InPesterModuleScope {
else {
function Invoke-DummyFunction {
param(
[Parameter(Mandatory = $true)]
[Parameter(Mandatory = $true, ParameterSetName = 'PrimarySet')]
[Alias('First', 'Another')]
$MandatoryParam,

[Parameter(ParameterSetName = 'PrimarySet')]
[ValidateNotNullOrEmpty()]
[DateTime]$ParamWithNotNullOrEmptyValidation = (Get-Date),

Expand Down Expand Up @@ -323,6 +325,38 @@ InPesterModuleScope {
$err.Exception.Message | Verify-Equal "Expected command Invoke-DummyFunction to have a parameter ParamWithNotNullOrEmptyValidation, which is mandatory, of type [System.TimeSpan], the default value to be 'wrong value' and has ArgumentCompletion, because of reasons, but it wasn't mandatory, it was of type [System.DateTime], the default value was '(Get-Date)' and has no ArgumentCompletion."
}
}

Context 'Using InParameterSet' {
It "passes if parameter <ParameterName> exist in parameter set <ParameterSetName>" -TestCases @(
@{ParameterName = 'ParamWithNotNullOrEmptyValidation'; ParameterSetName = 'PrimarySet' }
) {
Get-Command 'Invoke-DummyFunction' | Should -HaveParameter $ParameterName -InParameterSet $ParameterSetName
}

It 'passes if parameter <ParameterName> exist in parameter set <ParameterSetName> and is mandatory' -TestCases @(
@{ParameterName = 'MandatoryParam'; ParameterSetName = 'PrimarySet' }
) {
Get-Command 'Invoke-DummyFunction' | Should -HaveParameter $ParameterName -InParameterSet $ParameterSetName -Mandatory
}

It 'fails if parameter <ParameterName> does not exist at all or not in parameter set <ParameterSetName>' -TestCases @(
@{ParameterName = 'NonExistingParam'; ParameterSetName = 'PrimarySet' }
@{ParameterName = 'ParamWithNotNullOrEmptyValidation'; ParameterSetName = 'NonExistingSet' }
@{ParameterName = 'ParamWithScriptValidation'; ParameterSetName = 'PrimarySet' }
) {
$err = { Get-Command 'Invoke-DummyFunction' | Should -HaveParameter $ParameterName -InParameterSet $ParameterSetName } | Verify-AssertionFailed
$err.Exception.Message | Verify-Equal "Expected command Invoke-DummyFunction to have a parameter $ParameterName in parameter set $ParameterSetName, but the parameter is missing."
}

It 'fails if parameter <ParameterName> exists in parameter set <ParameterSetName> but is not mandatory' -TestCases @(
@{ParameterName = 'ParamWithNotNullOrEmptyValidation'; ParameterSetName = 'PrimarySet' }
) {
$err = { Get-Command 'Invoke-DummyFunction' | Should -HaveParameter $ParameterName -InParameterSet $ParameterSetName -Mandatory } | Verify-AssertionFailed
$err.Exception.Message | Verify-Equal "Expected command Invoke-DummyFunction to have a parameter $ParameterName in parameter set $ParameterSetName, which is mandatory, but it wasn't mandatory."
}

# -InParameterSet only affects if parameter exist and -Mandatory atm. Only appends a filter in the error for the remaining options
}
}

Describe "Should -Not -HaveParameter" {
Expand Down Expand Up @@ -492,6 +526,25 @@ InPesterModuleScope {
$err.Exception.Message | Verify-Equal "Expected command Invoke-DummyFunction to not have a parameter $ParameterName, not of type [$ExpectedType], the default value not to be '$ExpectedValue' and has ArgumentCompletion, because of reasons, but it was of type [$ExpectedType], the default value was '$ExpectedValue' and has ArgumentCompletion."
}
}

Context 'Using InParameterSet' {
It 'passes if parameter <ParameterName> does not exist at all or not in parameter set <ParameterSetName>' -TestCases @(
@{ParameterName = 'NonExistingParam'; ParameterSetName = 'PrimarySet' }
@{ParameterName = 'ParamWithScriptValidation'; ParameterSetName = 'PrimarySet' }
@{ParameterName = 'ParamWithNotNullOrEmptyValidation'; ParameterSetName = 'NonExistingSet' }
) {
Get-Command 'Invoke-DummyFunction' | Should -Not -HaveParameter $ParameterName -InParameterSet $ParameterSetName
}

It 'fails if parameter <ParameterName> exist in parameter set <ParameterSetName>' -TestCases @(
@{ParameterName = 'ParamWithNotNullOrEmptyValidation'; ParameterSetName = 'PrimarySet' }
) {
$err = { Get-Command 'Invoke-DummyFunction' | Should -Not -HaveParameter $ParameterName -InParameterSet $ParameterSetName } | Verify-AssertionFailed
$err.Exception.Message | Verify-Equal "Expected command Invoke-DummyFunction to not have a parameter $ParameterName in parameter set $ParameterSetName, but the parameter exists."
}

# -Not -HaveParameter only supports parameter existing atm. Extend when not mandatory etc is possible.
}
}
}

Expand Down

0 comments on commit 08998af

Please sign in to comment.