1

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.

Efie
  • 1,430
  • 2
  • 14
  • 34
  • I get the error: Cannot find an overload for "escape" and the argument count: 2. To be clear I want it to be case-sensitive and right now it's not. For a single line there is - FileContentMatch and - FileContentMatchExactly but it doesn't look like there is a similar call for multiline – Efie Jun 17 '20 at 13:58
  • Try `"(?-i)" + $([regex]::escape($matchString))` to enforce case sensitivity – Wiktor Stribiżew Jun 17 '20 at 14:26

1 Answers1

1

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

Mark Wragg
  • 22,105
  • 7
  • 39
  • 68
  • 1
    I actually had already submitted a feature request just before you posted. This worked perfectly. Thank you! – Efie Jun 17 '20 at 14:33
  • No problem :). I just edited with a slight alternative of using the `-MatchExactly` assertion rather than `-Be $True` as you then get a more detailed error when it doesn't pass. – Mark Wragg Jun 17 '20 at 14:44
  • You're one step ahead of me I was just trying to figure out a way to do that in case I hit an error. Cheers! – Efie Jun 17 '20 at 14:53