Pester icon indicating copy to clipboard operation
Pester copied to clipboard

Improve Should -BeLike for arrays

Open DarkLite1 opened this issue 6 years ago • 12 comments

It would be nice to be able to test an element in an array for matching a specific string.

For example:

$Collection = @('xxx disabled xxx', 'xxx incorrect')

Describe 'test' {
    it 'should be green' {
        $Collection | Should -BeLike '*disabled*'
    }
    it 'should be green' {
        $Collection | Should -Match '*disabled*'
    }
    it 'suggestion' {
        $Collection | Should -BeInLike '*disabled*'
    }
    it 'working workaround' {
        $Collection.where( { $_ -match 'disabled' }) | Should -BeTrue
    }
}

It would be great if this would be supported by the Should command.

DarkLite1 avatar Jun 21 '19 06:06 DarkLite1

To match an element in an array you use -Contain:

$Collection = @('xxx disabled xxx', 'xxx incorrect')

Describe 'test' {
    It "Using Contain" {
        $Collection | Should -Contain "xxx disabled xxx"
    }
}

martin9700 avatar Aug 13 '19 15:08 martin9700

Thank you @martin9700 but -Contain looks for an exact match in the collection while the intention here is to find a partial match in the collection.

DarkLite1 avatar Aug 14 '19 05:08 DarkLite1

I see now. Basically asking to have -BeLike act more like -Like. Another workaround, a little more elegant:

it 'should be green too' {
   $Collection -like "*disabled*"
}

All the It function is really looking for is $true or $false so you can feed that information to it directly without using Should.

martin9700 avatar Aug 14 '19 11:08 martin9700

True! Didn't think about that as I was in the Pester mindset. But your workaround is indeed very elegant. I'll consider using that in the meantime,. Thank you for your insights.

DarkLite1 avatar Aug 14 '19 11:08 DarkLite1

Hmmm... After trying the following code it's returning success while it should fail:

$Collection = @('apples', 'kiwi')

Describe 'test' {
    it 'should not be green but it is' {
       $Collection -like "*disabled*"
    }
}

Maybe I made an error somewhere.... But otherwise, this is not a valid workaround. I'm afraid

DarkLite1 avatar Aug 14 '19 11:08 DarkLite1

Bummer, that's why contains exists is to look at each element. I think your Where solution may be the only way, we're now talking about functionality that stands outside what PowerShell can do itself.

martin9700 avatar Aug 14 '19 12:08 martin9700

Let's see if it's possible to implement my feature request in the Pester suit. Thanks anyhow for the help Maritn, much appreciated.

DarkLite1 avatar Aug 14 '19 12:08 DarkLite1

@DarkLite1 you did not make an error, test won't fail unless something throws an exception. Your expression just returns false, which the framework ignores.

I think you are looking for the functionality of Assert-Any or Assert-All from my assert module.

nohwnd avatar Aug 20 '19 09:08 nohwnd

I ran into a similar issue where I had a function that was returning two lines of string instead of 1. I wanted to use -BeLike with a matcher like 'msg to match' But it kept throwing an error. I found the Where method up above actually worked for this case as well

Veretax avatar Dec 23 '19 20:12 Veretax

@nohwnd assert-any and assert-all are not actually the same as this request. What I would like Pester to do is to match a piece of an item in an array (with wildcards for example or simply with -match.

$Collection = @('Banana', 'Grape')

The test would pass on $Collection -BeLike '*pe*' and would fail on $Collection -BeLike '*nnn*'.

DarkLite1 avatar Jan 06 '20 08:01 DarkLite1

@DarkLite1 I am not sure I follow what you want. In your code examples it looks like you are adding your own operators. Or should those be parameters to a function (like with the modern where syntax)? How is that different from the Assert-All / Assert-Any in Assert? That allows you to set a predicate that runs on each item right?

It would be (writing from memory) :

$Collection | Assert-Any { $_ -like '*nnn*' }

And that would pass if at least one item would pass the predicate.

nohwnd avatar Jan 06 '20 09:01 nohwnd

You are correct, I was wrong about assert-any as I assumed that one item in the array needs to be equal to the requested item. Maybe -ContainsLike would've been a better suggestion for the Pester code base. It would avoid the need for using the .where method or for installing an extra module.

DarkLite1 avatar Jan 06 '20 09:01 DarkLite1