Search code examples
regexpowershellunit-testingpester

Case sensitive option for Pester's -FileContentMatchMultiline in PowerShell


I have a dozen lines or so that need to be consistent across multiple .ps1 files. I was able to get this working using the -FileContentMatchMultiline functionality in Pester but I need the match to be case sensitive. Is there any simple way to do this?

Here is what I have currently:

It "Has all the lines below, but case sensitive" {
        Get-ChildItem $directoryOfFilesToCheck | ForEach-Object {
            $matchstring = @'
$var1 = Line one blah blah blah
$var2 = Line two blah blah blah 
$var3 = Line three blah blah blah
'@
            $_ | Should -FileContentMatchMultiline $([regex]::escape($matchString))
        }

    }

The problem is that it would also match if the files contained:

$var1 = Line one BLAH Blah blAH
$var2 = Line two BLAH Blah blAH 
$var3 = Line three BLAH Blah blAH

This is important because in the file there are function calls that are case sensitive because they are used by a program running the script.


Solution

  • Unfortunately it seems Pester doesn't have a FileContentMatchExactlyMultiline assertion at the moment, but looking at how FileContentMatchMultiline works it is this:

    $succeeded = [bool] ((& $SafeCommands['Get-Content'] $ActualValue -Delimiter ([char]0)) -match $ExpectedContent)
    

    So it looks like you could simply roll your own equivalent of that by doing this as a workaround:

    Describe 'MyTests' {
    
        It "Has all the lines below, but case sensitive" {
    
            $matchstring = @'
    $var1 = Line one blah blah blah
    $var2 = Line two blah blah blah 
    $var3 = Line three blah blah blah
    '@
    
            Get-ChildItem $directoryOfFilesToCheck | ForEach-Object {       
                $ActualValue = (Get-Content $_.FullName -Delimiter [char]0)
                $ActualValue -cmatch $([regex]::escape($matchstring)) | Should -Be $True
            }
        }
    }
    

    This just switches -match to -cmatch which makes it case sensitive.

    Another option would be to use the -MatchExactly assertion having got the file content into $ActualValue as above:

    $ActualValue | Should -MatchExactly $([regex]::escape($matchstring))
    

    Contributing a FileContentMatchExactlyMultiline assertion to Pester doesn't seem like it would be that much work based on the above. It would be worth adding an issue for it here: https://github.com/pester/Pester/issues