pester / Pester

Pester is the ubiquitous test and mock framework for PowerShell.
https://pester.dev/
Other
3.08k stars 470 forks source link

Evaluate parameter in a parameter set #2227

Closed johlju closed 1 year ago

johlju commented 2 years ago

Checklist

Summary of the feature request

As a user I would like to validate that a specific parameter set exist and that it contain the expect parameters.

How should it work?

If HaveParameter would learn CommandParameterSetInfo we could use that to pass to Should.

It 'Should have have correct parameters in parameters sets' {
    $parmetersSet = (Get-Command -Name 'New-SqlDscAudit').ParameterSets | Where-Object Name -EQ 'Set1'
    $parameterSet | Should -HaveParameter 'MyParameter'
    $parameterSet | Should -HaveParameter 'Set1Parameter'

    $parmetersSet = (Get-Command -Name 'New-SqlDscAudit').ParameterSets | Where-Object Name -EQ 'Set2'
    $parameterSet | Should -HaveParameter 'MyParameter'
    $parameterSet | Should -HaveParameter 'Set2Parameter'
}

Another option is to add HaveParameterSet with an optional parameter WithParameter.

It 'Should have have correct parameters in parameters sets' {
    $commandInfo = Get-Command -Name 'Get-Something')

    $commandInfo | Should -HaveParameterSet 'MySetName1'
    $commandInfo | Should -HaveParameterSet 'MySetName2' -WithParameter 'MyParameter'
    $commandInfo | Should -HaveParameterSet 'MySetName3' -WithParameter @('MyParameter1', 'MyParameter2')
}
fflaten commented 2 years ago

Good suggestion. Parameter set support is lacking in general.

Noticed it recently while looking at -Mandatory which will pass if the parameter is mandatory in any set, but there's no way to specify which.

Would a -InParameterSet 'SetName123' parameter be more intuitive maybe? Ex

(Get-Command abc123) | Should -HaveParameter 'MyParameter' -InParameterSet 'Set1' -Mandatory -DefaultValue '123'

You second suggestion would be hard to combine with Mandatory, DefaultValue, Type ++

johlju commented 2 years ago

InParameterSet would work too, didn't think of looking at it from that angle.

Then this should work too and is also intuitive:

(Get-Command abc123) | Should -Not -HaveParameter 'MyParameter' -InParameterSet 'Set1'
jeffpatton1971 commented 1 year ago

When can something like this be expected to be available? In the interim @fflaten do you have thoughts on testing for a parameter that is mandatory in one set and not mandatory in another?

jeffpatton1971 commented 1 year ago

I like this code below for testing if a parameter is in the correct set! nice

It 'Should have have correct parameters in parameters sets' {
    $parmetersSet = (Get-Command -Name 'New-SqlDscAudit').ParameterSets | Where-Object Name -EQ 'Set1'
    $parameterSet | Should -HaveParameter 'MyParameter'
    $parameterSet | Should -HaveParameter 'Set1Parameter'

    $parmetersSet = (Get-Command -Name 'New-SqlDscAudit').ParameterSets | Where-Object Name -EQ 'Set2'
    $parameterSet | Should -HaveParameter 'MyParameter'
    $parameterSet | Should -HaveParameter 'Set2Parameter'
}
jeffpatton1971 commented 1 year ago

@johlju I took your code and tweaked it a little

   It "ParameterSet should contain, DocumentId, HideId" {
    (Get-Command -Name 'Get-MongoDBDocument').Parameters['DocumentId'].ParameterSets.DocumentId | Should -Be $true
    (Get-Command -Name 'Get-MongoDBDocument').Parameters['HideId'].ParameterSets.DocumentId | Should -Be $true
   }

This works as expected, which got me thinking about how to test for mandatory in a given set

jeffpatton1971 commented 1 year ago

It's a little cludgy but until @fflaten gets the inparameterset available

first parameterset

   It "DocumentId should be Mandatory" {
    (Get-Command -Name 'Get-MongoDBDocument').Parameters['DocumentId'].ParameterSets.DocumentId.IsMandatory | Should -Be $true
   }

second parameterset

   It "DocumentId should not be Mandatory" {
    (Get-Command -Name 'Get-MongoDBDocument').Parameters['DocumentId'].ParameterSets.CollectionNameId.IsMandatory | Should -Not -Be $true
   }

You will need to specify the ParmaeterName and ParmeterSetName; and it looks rather awkward but does in fact work as expected, which helps me a lot.

fflaten commented 1 year ago

When can something like this be expected to be available?

Unclear as I'm busy at work the next month. Was hoping on some input by @nohwnd before committing to it. Feel free to submit a PR if you'd like to look into it. See https://pester.dev/docs/contributing/pull-requests . Source is here with tests in a matching file under /tst

In the interim @fflaten do you have thoughts on testing for a parameter that is mandatory in one set and not mandatory in another?

Not really. I'd probably go commandinfo -> ParameterSets (filter by name) -> Parameters (filter by name) -> IsMandatory, but just personal preference.

jeffpatton1971 commented 1 year ago

I get the work-life stuff, but I'm pretty swamped at work as well; if I get some time next week, I'll see if I can do a PR.

fflaten commented 1 year ago

Found some time and gave it a shot in linked PR. Still needs a review.