Pester icon indicating copy to clipboard operation
Pester copied to clipboard

Suggest to add an option to assert the correct number of items in a collection to Pester v6

Open johlju opened this issue 1 year ago • 5 comments

Checklist

Summary of the feature request

Currently the new assertions for Pester v6 does not support a way for just asserting the correct number of objects in a collection similar to v5's Should -HaveCount. To use command Should-BeCollection one must also provide the actual values in the collection for the assert ot work. Suggest to add a parameter SkipValueComparison or CountOnly to just assert the correct number of items.

How should it work?

Use a switch parameter and use the Expected positional parameter for the expected count number.

 1, 2, 3 | Should-BeCollection 3 -SkipValueComparison
# or
 1, 2, 3 | Should-BeCollection 3 -CountOnly

Use a named parameter to also pass the expected count number.

 1, 2, 3 | Should-BeCollection -SkipValueComparison 3
# or
 1, 2, 3 | Should-BeCollection -CountOnly 3

Or add a command Should-HaveCount. Example code:

function Should-HaveCount
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
        [ValidateNotNullOrEmpty()]
        [System.Object[]]
        $InputObject,

        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [int]
        $Expected
    )

    begin
    {
        $actualCount = 0
    }

    process
    {
        $InputObject.ForEach({$actualCount += 1})
    }

    end
    {
        if ($actualCount -ne $Expected)
        {
            Write-Information -MessageData "Expected $Expected items, but got $actualCount" -InformationAction 'Continue'
        }
        else 
        {
            Write-Information -MessageData "Got correct count!" -InformationAction 'Continue'
        }
    }
}

$someCollection = @('a', 'b', 'c')
Should-HaveCount -InputObject $someCollection -Expected 3
$someCollection | Should-HaveCount -Expected 3
$someCollection | Should-HaveCount -Expected 4

johlju avatar Jul 08 '24 08:07 johlju

It might be another way we are expected to handle this in v6, I added this issue to discuss how the Should -HaveCount should be converted to the (future) Pester v6 syntax. 🙂

johlju avatar Jul 08 '24 08:07 johlju

My immediate suggestion would be to recommend using @().Count | Should -Be* 2 etc. going forward.

It's easy to use, works with Should-Be/BeGreaterThan*/BeLessThan* and we avoid issues with dictionary and typed objects (e.g. [System.Array]) not working because we struggle with special collections vs single-item arrays. Just include a bunch of examples in our migration docs to cover the common scenarios.

@nohwnd: Does the new Collect-Input approach make the collection vs single item array issue solvable?

fflaten avatar Jul 08 '24 16:07 fflaten

I was thinking 1, 2, 3 | Should-BeCollection -Count 3 , but using just .Count sounds like a good solution, that is what we would have done in the assertion anyway, minus the problems with |.

Does the new Collect-Input approach make the collection vs single item array issue solvable?

No. We can tell when you pass the value by pipeline, or by parameter, but we cannot distinguish @(1) and 1 when passed by pipeline, because the internal collection does not distinguish that.

nohwnd avatar Jul 10 '24 18:07 nohwnd

So... Will there be a Count parameter to Should-BeCollection or will we just update documentation to say that .Count should be used from now on? I'm good with either way, just want a hint so I know in what direction I should write the conversion code. 🙂

...but we cannot distinguish @(1) and 1...

Assuming this is already a problem in v5? I would expect that 1 would be equal to Should-BeCollection -Count 1 if it is passed to that command.

johlju avatar Jul 11 '24 14:07 johlju

I will add -Count to Should-BeCollection, but please start with .Count, it will take me some time.

nohwnd avatar Jul 12 '24 13:07 nohwnd