From 9ad45fce7c499dc8cc168a32a9c19b3c33f595f2 Mon Sep 17 00:00:00 2001 From: Johan Ljunggren Date: Sun, 14 Jul 2024 15:33:26 +0200 Subject: [PATCH] Add support for BeIn (#26) --- .DS_Store | Bin 6148 -> 0 bytes .gitignore | 1 + CHANGELOG.md | 1 + source/Private/Convert-ShouldBeIn.ps1 | 246 +++++++++++++++++ source/Private/Convert-ShouldNotThrow.ps1 | 2 +- source/Private/Get-PesterCommandParameter.ps1 | 2 +- ...Block.ps1 => Get-PipelineBeforeShould.ps1} | 6 +- source/Private/Test-IsPipelinePart.ps1 | 40 +++ source/Public/Convert-PesterSyntax.ps1 | 14 + source/WikiSource/Pester_v5_Conversion.md | 15 +- tests/ShouldBe.v5.mocktest.ps1 | 255 ------------------ .../Unit/Private/Convert-ShouldBeIn.tests.ps1 | 240 +++++++++++++++++ ...ps1 => Get-PipelineBeforeShould.Tests.ps1} | 16 +- .../Private/Test-IsPipelinePart.tests.ps1 | 70 +++++ .../Public/Convert-PesterSyntax.tests.ps1 | 117 ++++++++ 15 files changed, 754 insertions(+), 271 deletions(-) delete mode 100644 .DS_Store create mode 100644 source/Private/Convert-ShouldBeIn.ps1 rename source/Private/{Get-ShouldThrowScriptBlock.ps1 => Get-PipelineBeforeShould.ps1} (93%) create mode 100644 source/Private/Test-IsPipelinePart.ps1 delete mode 100644 tests/ShouldBe.v5.mocktest.ps1 create mode 100644 tests/Unit/Private/Convert-ShouldBeIn.tests.ps1 rename tests/Unit/Private/{Get-ShouldThrowScriptBlock.Tests.ps1 => Get-PipelineBeforeShould.Tests.ps1} (86%) create mode 100644 tests/Unit/Private/Test-IsPipelinePart.tests.ps1 diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index df013cea57b2d3824178da67dd969399d1a9f6a3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHK!AiqG5S?wSO(|jz3VI88E!fuDiXg5Z!Um1gHUkg-TecVDp90IO&QMjE7LDIYJmg42M!x#PI7+id<4qKbrH#$9Rko_ut@|LS zZsuj@RH3zl_4^ptjSKN#;dKI8q5w5Ms#9Rg?sB+LhxZNL8+@2ds)! z8PxV?v*uB&Znus*^SV82Hrv?gv>Wqz#o9eMJUJgc#!rcS*4zsG4V7#eT)+z&KWua2 zj*?g=_ZYdDWs%Lu3@`)Cz?v~&jybEkX8YppFaylM?-`);!A2!?4CWfu(SZ$JA8EWq zNP;%KB?xVUj=@|bj-Uvgil|eCd145ij(*$3IRs8Rs!83-dw|YIXG6DjbBP zky~bf8CYhZsJk_)|EJ%-|Cf`v#|$t7YsG*l_1%6Kw`6MT%I2un+NgJ^Bovox{76AV im12ygQoM(%1pPJ{h>pQrBYIHyBA{sCh8g%%2HpV!*-`KS diff --git a/.gitignore b/.gitignore index 17c483d..67ad94f 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ output/ markdownissues.txt node_modules package-lock.json +.DS_Store diff --git a/CHANGELOG.md b/CHANGELOG.md index 1116eb3..63df71e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - BeFalse - BeGreaterOrEqual - BeGreaterThan + - BeIn - BeLessOrEqual - BeLessThan - BeLike diff --git a/source/Private/Convert-ShouldBeIn.ps1 b/source/Private/Convert-ShouldBeIn.ps1 new file mode 100644 index 0000000..f3e188d --- /dev/null +++ b/source/Private/Convert-ShouldBeIn.ps1 @@ -0,0 +1,246 @@ +<# + .SYNOPSIS + Converts a command `Should -BeIn` to the specified Pester syntax. + + .DESCRIPTION + The Convert-ShouldContain function is used to convert a command `Should -BeIn` to + the specified Pester syntax. + + .PARAMETER CommandAst + The CommandAst object representing the command to be converted. + + .PARAMETER Pester6 + Specifies that the command should be converted to Pester version 6 syntax. + + .PARAMETER UseNamedParameters + Specifies whether to use named parameters in the converted syntax. + + .PARAMETER UsePositionalParameters + Specifies whether to use positional parameters in the converted syntax, + where supported. + + .EXAMPLE + $commandAst = [System.Management.Automation.Language.Parser]::ParseInput('Should -BeIn @("Test", "Test2")') + Convert-ShouldContain -CommandAst $commandAst -Pester6 + + This example converts the `Should -BeIn @("Test", "Test2")` command to Pester 6 syntax. + + .NOTES + Pester 5 Syntax: + Should -BeIn [[-ActualValue] ] [[-ExpectedValue] ] [[-Because] ] [-Not] + + Positional parameters: + Position 1: ExpectedValue + Position 2: Because + Position 3: ActualValue + + Pester 6 Syntax: + Should-ContainCollection [-Actual] ] [-Expected] [-Because ] + Should-NotContainCollection [[-Actual] ] [-Expected] [-Because ] + + Positional parameters: + Position 1: Expected + Position 2: Actual +#> +function Convert-ShouldBeIn +{ + [CmdletBinding()] + [OutputType([System.String])] + param + ( + [Parameter(Mandatory = $true)] + [System.Management.Automation.Language.CommandAst] + $CommandAst, + + [Parameter(Mandatory = $true, ParameterSetName = 'Pester6')] + [System.Management.Automation.SwitchParameter] + $Pester6, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $UseNamedParameters, + + [Parameter()] + [System.Management.Automation.SwitchParameter] + $UsePositionalParameters + ) + + $assertBoundParameterParameters = @{ + BoundParameterList = $PSBoundParameters + MutuallyExclusiveList1 = @('UseNamedParameters') + MutuallyExclusiveList2 = @('UsePositionalParameters') + } + + Assert-BoundParameter @assertBoundParameterParameters + + Write-Debug -Message ($script:localizedData.Convert_Should_Debug_ParsingCommandAst -f $CommandAst.Extent.Text) + + # Determine if the command is negated + $isNegated = Test-PesterCommandNegated -CommandAst $CommandAst + + $sourceSyntaxVersion = Get-PesterCommandSyntaxVersion -CommandAst $CommandAst + + # Parse the command elements and convert them to Pester 6 syntax + if ($PSCmdlet.ParameterSetName -eq 'Pester6') + { + Write-Debug -Message ($script:localizedData.Convert_Should_Debug_ConvertingFromTo -f $sourceSyntaxVersion, '6') + + # Add the correct Pester command based on negation + if ($isNegated) + { + $newExtentText = 'Should-NotContainCollection' + } + else + { + $newExtentText = 'Should-ContainCollection' + } + + $getPesterCommandParameterParameters = @{ + CommandAst = $CommandAst + CommandName = 'Should' + IgnoreParameter = @( + 'BeIn' + 'Not' + ) + PositionalParameter = @( + 'ExpectedValue' + 'Because' + 'ActualValue' + ) + NamedParameter = @() + } + + $commandParameters = Get-PesterCommandParameter @getPesterCommandParameterParameters + + $pipelineExtentText = Get-PipelineBeforeShould -CommandAst $CommandAst -ParsePipeline + + # NOTE! This switches the arguments between expected and actual values. + $originalActualValue = $commandParameters.ActualValue + $commandParameters.ActualValue = $commandParameters.ExpectedValue + $commandParameters.ExpectedValue = $originalActualValue + + # If we do not end up with a value for ExpectValue we need to get it from the pipeline. + $isPipeline = $null -eq $commandParameters.ExpectedValue + + if ($isPipeline) + { + <# + ActualValue was not part of the arguments as either positional or + named parameter, assume there is a pipeline and the original + ActualValue should be converted to Expected. Also using the + position and positional property values from original ActualValue + for the new ExpectedValue. + #> + $commandParameters.ExpectedValue = @{ + Position = $commandParameters.ActualValue.Position + Positional = $commandParameters.ActualValue.Positional + ExtentText = '({0})' -f $pipelineExtentText + } + + <# + We must put the new actual value on the pipeline before the Should + command, so we need to make sure it is not added as positional. + #> + $commandParameters.ActualValue.Position = 0 + $commandParameters.ActualValue.Positional = $false + } + + # Parameter 'Because' is only supported as named parameter in Pester 6 syntax. + if ($commandParameters.Because) + { + $commandParameters.Because.Positional = $false + } + + # Determine if named or positional parameters should be forcibly used + if ($UseNamedParameters.IsPresent) + { + $commandParameters.Keys.ForEach({ $commandParameters.$_.Positional = $false }) + } + elseif ($UsePositionalParameters.IsPresent) + { + # First set all to named parameters + $commandParameters.Keys.ForEach({ $commandParameters.$_.Positional = $false }) + + <# + If a previous positional parameter is missing then the ones behind + it cannot be set to positional. + #> + if ($commandParameters.ExpectedValue) + { + $commandParameters.ExpectedValue.Positional = $true + + # If the actual value was originally passed in the pipeline, we should do the same. + if ($commandParameters.ActualValue -and -not $isPipeline) + { + $commandParameters.ActualValue.Positional = $true + } + } + } + + $newExtentText += $commandParameters.ExpectedValue.Positional ? (' {0}' -f $commandParameters.ExpectedValue.ExtentText) : '' + $newExtentText += $commandParameters.ActualValue.Positional ? (' {0}' -f $commandParameters.ActualValue.ExtentText) : '' + + # Holds the new parameter names so they can be added in alphabetical order. + $parameterNames = @() + + foreach ($currentParameter in $commandParameters.Keys) + { + if ($commandParameters.$currentParameter.Positional -eq $true) + { + continue + } + + switch ($currentParameter) + { + 'ActualValue' + { + if ($isPipeline) + { + continue + } + + $parameterNames += @{ + Actual = 'ActualValue' + } + + break + } + + 'ExpectedValue' + { + $parameterNames += @{ + Expected = 'ExpectedValue' + } + + break + } + + default + { + $parameterNames += @{ + $currentParameter = $currentParameter + } + + break + } + } + } + + # This handles the named parameters in the command elements, added in alphabetical order. + foreach ($currentParameter in $parameterNames.Keys | Sort-Object) + { + $originalParameterName = $parameterNames.$currentParameter + + $newExtentText += ' -{0} {1}' -f $currentParameter, $commandParameters.$originalParameterName.ExtentText + } + } + + if ($isPipeline) + { + $newExtentText = '{0} | {1}' -f $commandParameters.ActualValue.ExtentText, $newExtentText + } + + Write-Debug -Message ($script:localizedData.Convert_Should_Debug_ConvertedCommand -f $CommandAst.Extent.Text, $newExtentText) + + return $newExtentText +} diff --git a/source/Private/Convert-ShouldNotThrow.ps1 b/source/Private/Convert-ShouldNotThrow.ps1 index 3c367a5..a588502 100644 --- a/source/Private/Convert-ShouldNotThrow.ps1 +++ b/source/Private/Convert-ShouldNotThrow.ps1 @@ -97,7 +97,7 @@ function Convert-ShouldNotThrow Must extract the scriptblock from the CommandAst extent, the scriptblock is passed as the parameter ActualValue or passed thru the pipeline. #> - $newExtentText = '$null = & ({0})' -f (Get-ShouldThrowScriptBlock -CommandAst $CommandAst -ParameterName 'ActualValue' -ParsePipeline) + $newExtentText = '$null = & ({0})' -f (Get-PipelineBeforeShould -CommandAst $CommandAst -ParameterName 'ActualValue' -ParsePipeline) } else { diff --git a/source/Private/Get-PesterCommandParameter.ps1 b/source/Private/Get-PesterCommandParameter.ps1 index 8710070..cdc182a 100644 --- a/source/Private/Get-PesterCommandParameter.ps1 +++ b/source/Private/Get-PesterCommandParameter.ps1 @@ -149,7 +149,7 @@ function Get-PesterCommandParameter $positionalParameterHashtable.$parameter = @{ Position = $positionalCounter Positional = $true - ExtentText = $commandElement[$elementCounter].Extent.Text #? $commandElement.Extent.Text : $null + ExtentText = $commandElement[$elementCounter].Extent.Text } # Increment the positional counter. diff --git a/source/Private/Get-ShouldThrowScriptBlock.ps1 b/source/Private/Get-PipelineBeforeShould.ps1 similarity index 93% rename from source/Private/Get-ShouldThrowScriptBlock.ps1 rename to source/Private/Get-PipelineBeforeShould.ps1 index bcbb100..c93e1df 100644 --- a/source/Private/Get-ShouldThrowScriptBlock.ps1 +++ b/source/Private/Get-PipelineBeforeShould.ps1 @@ -3,7 +3,7 @@ Retrieves the script block associated with a pipeline or parameter. .DESCRIPTION - The Get-ShouldThrowScriptBlock function is used to retrieve the script block + The Get-PipelineBeforeShould function is used to retrieve the script block associated with a pipeline or parameter. It can be used to extract the script block from a pipeline or from a specific parameter. @@ -23,12 +23,12 @@ The function returns the text of the script block if found, otherwise it returns $null. .EXAMPLE - Get-ShouldThrowScriptBlock -CommandAst $commandAst -ParameterName 'ActualValue' -ParsePipeline + Get-PipelineBeforeShould -CommandAst $commandAst -ParameterName 'ActualValue' -ParsePipeline Retrieves the script block associated with the specified command AST and parameter name, parsing the pipeline if necessary. #> -function Get-ShouldThrowScriptBlock +function Get-PipelineBeforeShould { [CmdletBinding()] [OutputType([System.String])] diff --git a/source/Private/Test-IsPipelinePart.ps1 b/source/Private/Test-IsPipelinePart.ps1 new file mode 100644 index 0000000..e761782 --- /dev/null +++ b/source/Private/Test-IsPipelinePart.ps1 @@ -0,0 +1,40 @@ + +<# + .SYNOPSIS + Determines if a command is part of a pipeline. + + .DESCRIPTION + The Test-IsPipelinePart function checks if a given command is part of a + pipeline. It examines the parent of the CommandAst and determines if it + is a PipelineAst. + + .PARAMETER CommandAst + The CommandAst object representing the command to be checked. + + .EXAMPLE + Test-IsPipelinePart -CommandAst $commandAst + + Determines if the specified command is part of a pipeline. + + .OUTPUTS + System.Boolean + + Returns $true if the command is part of a pipeline, otherwise returns $false. +#> +function Test-IsPipelinePart +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter(Mandatory = $true)] + [System.Management.Automation.Language.CommandAst] + $CommandAst + ) + + # Check if the parent of the CommandAst is a PipelineAst + $isPartOfPipeline = $CommandAst.Parent -and $CommandAst.Parent -is [System.Management.Automation.Language.PipelineAst] -and $CommandAst.Parent.PipelineElements.Count -gt 1 + + # Return true if part of a pipeline, false otherwise + return $isPartOfPipeline +} diff --git a/source/Public/Convert-PesterSyntax.ps1 b/source/Public/Convert-PesterSyntax.ps1 index 8f53e49..167c17b 100644 --- a/source/Public/Convert-PesterSyntax.ps1 +++ b/source/Public/Convert-PesterSyntax.ps1 @@ -313,6 +313,20 @@ function Convert-PesterSyntax break } + 'BeIn' + { + $newExtentText = Convert-ShouldBeIn -CommandAst $commandAst @convertParameters -ErrorAction 'Stop' + + if ((Test-IsPipelinePart -CommandAst $commandAst -ErrorAction 'Stop')) + { + # Change start and end offsets to replace the entire commandAst.Parent.Extent.Text. + $startOffset = $commandAst.Parent.Extent.StartOffset + $endOffset = $commandAst.Parent.Extent.EndOffset + } + + break + } + default { Write-Warning -Message ($script:localizedData.Convert_PesterSyntax_Warning_UnsupportedCommandOperator -f $operatorName, $commandAst.Extent.Text) diff --git a/source/WikiSource/Pester_v5_Conversion.md b/source/WikiSource/Pester_v5_Conversion.md index 045b97a..40d91c4 100644 --- a/source/WikiSource/Pester_v5_Conversion.md +++ b/source/WikiSource/Pester_v5_Conversion.md @@ -19,16 +19,17 @@ Should operator name | Affirm | Negate | Notes --- | --- | --- | --- Be | `Should-Be` | `Should-NotBe` | - BeExactly | `Should-Be -CaseSensitive` | `Should-NotBe -CaseSensitive` | - -BeFalse | `Should-BeFalse` | `Should-BeTrue` | - +BeFalse | `Should-BeFalse` | `Should-BeTrue` | See 4) BeGreaterOrEqual | `Should-BeGreaterThanOrEqual` | `Should-BeLessThanOrEqual` | - BeGreaterThan | `Should-BeGreaterThan` | `Should-BeLessThan` | - +BeIn | `Should-ContainCollection` | `Should-NotContainCollection` | See 3) BeLessOrEqual | `Should-BeLessThanOrEqual` | `Should-BeGreaterThanOrEqual` | - BeLessThan | `Should-BeLessThan` | `Should-BeGreaterThan` | - BeLike | `Should-BeLikeString` | `Should-NotBeLikeString` | - BeLikeExactly | `Should-BeLikeString -CaseSensitive` | `Should-NotBeLikeString -CaseSensitive` | - BeNullOrEmpty | `Should-BeFalsy` | `Should-BeTruthy` | See 2) BeOfType | `Should-HaveType` | `Should-NotHaveType` | - -BeTrue | `Should-BeTrue` | `Should-BeFalse` | - +BeTrue | `Should-BeTrue` | `Should-BeFalse` | See 4) Contain | `Should-ContainCollection` | `Should-NotContainCollection` | - Match | `Should-MatchString` | `Should-NotMatchString` | - MatchExactly | `Should-MatchString -CaseSensitive` | `Should-NotMatchString -CaseSensitive` | - @@ -41,8 +42,16 @@ The conversion will parse the actual value, normally a scriptblock passed as parameter or through the pipeline, and convert it to be executed using the call operator (`&`) inside the `It`-block. Any output is passed to `$null` so that no output affects the Pester test object. -1) There are no exact command to convert to, but `Should-BeFalsy` and +2) There are no exact command to convert to, but `Should-BeFalsy` and `Should-BeTruthy` is similar. But there might be scenarios where the commands `Should-BeNull` or `Should-BeEmptyString` are better suited. But since the conversion has no way of knowing if those command are better suitable based on the AST the `Should-BeFalsy` and `Should-BeTruthy` are used. +3) This will switch the expected and actual values on the parameters and/or +the pipeline to be able to convert to `Should-ContainCollection` or +`Should-NotContainCollection`. +4) `BeTrue` and `BeFalse` does not work as they did in Pester 5, there it +was also possible to pass `$null` to `BeFalse` for it to pass which is not +allowed in Pester 6. If this happens then either the code being tested need +to be changed to always return boolean value `$true` or `$false`, or change +the test to use the Pester 6 commands `Should-BeFalsy` or `Should-BeTruthy`. diff --git a/tests/ShouldBe.v5.mocktest.ps1 b/tests/ShouldBe.v5.mocktest.ps1 deleted file mode 100644 index 4ce7a57..0000000 --- a/tests/ShouldBe.v5.mocktest.ps1 +++ /dev/null @@ -1,255 +0,0 @@ -<# - Tests Pester 5 syntax: Should [[-ActualValue] ] [-Be] [-Not] [-ExpectedValue ] [-Because ] -#> -Describe 'ShouldBe' { - # It 'Should be true' { - # $true | Should -Be $true - # } - - # It 'Should be false' { - # $false | Should -Be $false - # } - - It 'Should be true' { - $true | Should -BeTrue - } - - It 'Should be false' { - $false | Should -BeFalse - } - - It 'Should be false' { - Should -BeFalse 'because mock should test correct value' $false - } - - It 'Should be false' { - Should -BeFalse -Because 'because mock should test correct value' $false - } - - It 'Should be false' { - Should -BeFalse $false -Because 'because mock should test correct value' - } - - It 'Should be false' { - Should -BeFalse -Actual $false 'because mock should test correct value' - } - - It 'Should be false' { - Should -BeFalse 'because mock should test correct value' -Actual $false - } - - # It 'Should be true' { - # $false | Should -Not -Be $true - # } - - # It 'Should be false' { - # $true | Should -Be $false -Not - # } - - # It 'Should be true' { - # $false | Should -Not:$true -Be $true - # } - - It 'Should be true' { - $false | Should -Not:$true -BeTrue - } - - It 'Should be false' { - $false | Should -Not:$false -BeFalse - } - - # It 'Should be true' { - # Should -ActualValue $true -Be $true - # } - - It 'Should be true' { - Should -ActualValue $true -BeTrue - } - - # It 'Should be false' { - # Should -Not -ActualValue $true -Be $false - # } - - # It 'Should be false' { - # Should -Be $false -ActualValue $true -Not - # } - - It 'Should be false' { - Should -ActualValue $true -BeFalse -Not - } - - It 'Should be false' { - Should -ActualValue $true -Be -Not -ExpectedValue $false - } - - # It 'Should be false' { - # Should -ActualValue $true -Be -Not $false - # } - - # This is not allowed syntax - # It 'Should be true' { - # Should $true -Be $true - # } - - # This is not allowed syntax - # It 'Should be true' { - # Should $true -BeTrue - # } - - It 'Should be false' { - Should -Be $false 'mock should test correct value' $false - } - - It 'Should be false (with -Because)' { - Should -Be $false -Because 'mock should test correct value' $false - } - - It 'Should be false' { - Should $false 'mock should test correct value' $false -Be - } - - It 'Should be false' { - Should -BeExactly 'ExpectedString' 'mock should test correct value' 'ExpectedString' - } - - It 'Should be false' { - Should -Be 'ExpectedString' 'mock should test correct value' 'ExpectedString' - } - - # This is not allowed syntax, it generates an array of values 'a' and 'b' that cannot be compared to a single value - # It 'Should be false' { - # Should -Be @('a', 'b') 'because mock should test correct value' 'a' 'b' - # } - - It 'Should be true (v6)' { - Should-Be 'a' 'a' - } - - It 'Should be true (v6)' { - Should-Be 'a' 'a' -Because 'a should equal a' - } - - It 'Should be true (v6)' { - Should-Be 'a' -Because 'a should equal a' 'a' - } - - It 'Should be true (v6)' { - Should-Be -Because 'a should equal a' 'a' 'a' - } - - It 'Should throw' { - { throw 'hej' } | Should -Throw - } - - It 'Should throw' { - { throw 'hej' } | Should -Throw -Because 'Expected to throw' - } - - It 'Should throw' { - { throw 'hej' } | Should -Throw -Because 'Expected to throw' -ErrorId 'hej' - } - - It 'Should throw' { - { throw 'hej' } | Should -Throw -Because 'Expected to throw' -ErrorId 'hej' -ExpectedMessage 'hej' - } - - It 'Should throw' { - { throw 'hej' } | Should -Throw -Because 'Expected to throw' -ErrorId 'hej' -ExpectedMessage 'hej' -ExceptionType ([Exception]) - } - - It 'Should throw' { - { - Write-Error -Message 'MockErrorMessage' -ErrorId 'MockErrorId' -Category 'InvalidOperation' -TargetObject 'MockTargetObject' -ErrorAction 'Stop' - } | Should -Throw 'MockErrorMessage' - } - - It 'Should throw' { - { - Write-Error -Message 'MockErrorMessage' -ErrorId 'MockErrorId' -Category 'InvalidOperation' -TargetObject 'MockTargetObject' -ErrorAction 'Stop' - } | Should -Throw 'MockErrorMessage' 'MockErrorId' - } - - It 'Should throw' { - { - Write-Error -Message 'MockErrorMessage' -ErrorId 'MockErrorId' -Category 'InvalidOperation' -TargetObject 'MockTargetObject' -ErrorAction 'Stop' - } | Should -Throw 'MockErrorMessage' 'MockErrorId' ([System.Exception]) - } - - It 'Should throw' { - { - Write-Error -Message 'MockErrorMessage' -ErrorId 'MockErrorId' -Category 'InvalidOperation' -TargetObject 'MockTargetObject' -ErrorAction 'Stop' - } | Should -Throw 'MockErrorMessage' 'MockErrorId' ([System.Exception]) 'BecauseString' - } - - - # It 'Should throw' { - # { 1+1 } | Should -Throw -Because 'Expected to throw' -ErrorId 'hej' -ExpectedMessage 'hej' -ExceptionType ([Exception]) -Not - # } - - It 'Should throw' { - $errorPassThru = ({ throw 'hej' } | Should -Throw -Because 'Expected to throw' -ErrorId 'hej' -ExpectedMessage 'hej' -ExceptionType ([Exception]) -PassThru) - $errorPassThru.Exception.Message | Should -Be 'hej' - } - - It 'Should throw' { - { throw 'hej' } | Should -Throw 'hej' - } - - It 'Should throw with actual value' { - Should -Throw 'hej' -ActualValue { throw 'hej' } - } - - It 'Should throw using only positional parameters' { - { - Write-Error -Message 'MockErrorMessage' -ErrorId 'MockErrorId' -Category 'InvalidOperation' -TargetObject 'MockTargetObject' -ErrorAction 'Stop' - } | Should -Throw 'MockErrorMessage' 'MockErrorId' ([Microsoft.PowerShell.Commands.WriteErrorException]) 'MockBecauseString' - } - - # Not possible without curly braces (script block) - # It 'Should throw using only named parameters' { - # (1 + 1) | Should -Not -Throw -ExpectedMessage 'MockErrorMessage' -ErrorId 'MockErrorId' -ExceptionType ([Microsoft.PowerShell.Commands.WriteErrorException]) -Because 'MockBecauseString' - # } - - # Not supported in Pester 5 - # It 'Should BeOfType' { - # Should [System.String] $null 'ActualValue' -BeOfType - # } - - # Not supported in Pester 5 - # It 'Should BeOfType' { - # Should [System.String] 'ActualValue' 'mock must have correct type' -BeOfType - # } - - It 'Should BeOfType' { - Should [System.String] 'mock must have correct type' -ActualValue 'ActualValue' -BeOfType - } - - It 'Should BeOfType' { - 'ActualValue' | Should [System.String] 'mock must have correct type' -BeOfType - } - - It 'Should Match' { - Should -Match '^\[.+\]$' 'must match regex' '[Actual]' - } - - It 'Should MatchExactly' { - Should -MatchExactly '^\[.+\]$' 'must match regex' '[Actual]' - } - - It 'Should Contain' { - @('a', 'Expected') | Should -Contain 'Expected' 'must contain correct value' - } - - # This does not work. It is not possible to use the -ActualValue positional parameter with the -Contain parameter - # It 'Should Contain' { - # Should -Contain 'Expected' 'must contain correct value' @('a', 'Expected') - # } - - It 'Should BeGreaterThan' { - Should -BeGreaterThan 2 'must be higher' 3 - } - - It 'Should BeGreaterThan' { - Should -BeLike 'ExpectedString*' 'must be part of the string' 'ExpectedStringActualString' - } -} diff --git a/tests/Unit/Private/Convert-ShouldBeIn.tests.ps1 b/tests/Unit/Private/Convert-ShouldBeIn.tests.ps1 new file mode 100644 index 0000000..7294a49 --- /dev/null +++ b/tests/Unit/Private/Convert-ShouldBeIn.tests.ps1 @@ -0,0 +1,240 @@ +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } +} + +BeforeAll { + $script:dscModuleName = 'PesterConverter' + + Import-Module -Name $script:dscModuleName + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscModuleName +} + +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscModuleName -All | Remove-Module -Force +} + +Describe 'Convert-ShouldBeIn' { + Context 'When converting Pester 5 syntax to Pester 6 syntax' { + BeforeAll { + InModuleScope -ScriptBlock { + $PSDefaultParameterValues['Convert-ShouldBeIn:Pester6'] = $true + } + } + + AfterAll { + InModuleScope -ScriptBlock { + $PSDefaultParameterValues.Remove('Convert-ShouldBeIn:Pester6') + } + } + + Context 'When the tests are affirming' { + It 'Should convert `Should -BeIn @(''ExpectedValue1'', ''ExpectedValue2'') ''BecauseString'' ''ActualValue''` correctly' { + InModuleScope -ScriptBlock { + $mockCommandAstPester5 = { + Should -BeIn @('ExpectedValue1', 'ExpectedValue2') 'BecauseString' 'ActualValue' + }.Ast.Find({ $args[0] -is [System.Management.Automation.Language.CommandAst] }, $false) + + $result = Convert-ShouldBeIn -CommandAst $mockCommandAstPester5 + + $result | Should-BeString -CaseSensitive 'Should-ContainCollection ''ActualValue'' @(''ExpectedValue1'', ''ExpectedValue2'') -Because ''BecauseString''' + } + } + + It 'Should convert `Should -BeIn @(''ExpectedValue1'', ''ExpectedValue2'') -Because ''BecauseString'' ''ActualValue''` correctly' { + InModuleScope -ScriptBlock { + $mockCommandAstPester5 = { + Should -BeIn @('ExpectedValue1', 'ExpectedValue2') -Because 'BecauseString' 'ActualValue' + }.Ast.Find({ $args[0] -is [System.Management.Automation.Language.CommandAst] }, $false) + + $result = Convert-ShouldBeIn -CommandAst $mockCommandAstPester5 + + $result | Should-BeString -CaseSensitive 'Should-ContainCollection ''ActualValue'' @(''ExpectedValue1'', ''ExpectedValue2'') -Because ''BecauseString''' + } + } + + It 'Should convert `Should -BeIn -ExpectedValue @(''ExpectedValue1'', ''ExpectedValue2'') -Because ''BecauseString'' ''ActualValue''` correctly' { + InModuleScope -ScriptBlock { + $mockCommandAstPester5 = { + Should -BeIn -ExpectedValue @('ExpectedValue1', 'ExpectedValue2') -Because 'BecauseString' 'ActualValue' + }.Ast.Find({ $args[0] -is [System.Management.Automation.Language.CommandAst] }, $false) + + $result = Convert-ShouldBeIn -CommandAst $mockCommandAstPester5 + + $result | Should-BeString -CaseSensitive 'Should-ContainCollection ''ActualValue'' -Actual @(''ExpectedValue1'', ''ExpectedValue2'') -Because ''BecauseString''' + } + } + + It 'Should convert `Should -BeIn -ExpectedValue @(''ExpectedValue1'', ''ExpectedValue2'') -Because ''BecauseString'' -ActualValue ''ActualValue''` correctly' { + InModuleScope -ScriptBlock { + $mockCommandAstPester5 = { + Should -BeIn -ExpectedValue @('ExpectedValue1', 'ExpectedValue2') -Because 'BecauseString' -ActualValue 'ActualValue' + }.Ast.Find({ $args[0] -is [System.Management.Automation.Language.CommandAst] }, $false) + + $result = Convert-ShouldBeIn -CommandAst $mockCommandAstPester5 + + $result | Should-BeString -CaseSensitive 'Should-ContainCollection -Actual @(''ExpectedValue1'', ''ExpectedValue2'') -Because ''BecauseString'' -Expected ''ActualValue''' + } + } + + It 'Should convert `''ActualValue'' | Should -BeIn @(''ExpectedValue1'', ''ExpectedValue2'') -Because ''BecauseString''` correctly' { + InModuleScope -ScriptBlock { + $mockCommandAstPester5 = { + 'ActualValue' | Should -BeIn @('ExpectedValue1', 'ExpectedValue2') -Because 'BecauseString' + }.Ast.Find({ $args[0] -is [System.Management.Automation.Language.CommandAst] }, $false) + + $result = Convert-ShouldBeIn -CommandAst $mockCommandAstPester5 + + $result | Should-BeString -CaseSensitive '@(''ExpectedValue1'', ''ExpectedValue2'') | Should-ContainCollection (''ActualValue'') -Because ''BecauseString''' + } + } + + It 'Should convert `''ActualValue'' | Should -BeIn -Because ''BecauseString'' -ExpectedValue @(''ExpectedValue1'', ''ExpectedValue2'')` correctly' { + InModuleScope -ScriptBlock { + $mockCommandAstPester5 = { + 'ActualValue' | Should -BeIn -Because 'BecauseString' -ExpectedValue @('ExpectedValue1', 'ExpectedValue2') + }.Ast.Find({ $args[0] -is [System.Management.Automation.Language.CommandAst] }, $false) + + $result = Convert-ShouldBeIn -CommandAst $mockCommandAstPester5 + + $result | Should-BeString -CaseSensitive '@(''ExpectedValue1'', ''ExpectedValue2'') | Should-ContainCollection -Because ''BecauseString'' -Expected (''ActualValue'')' + } + } + } + + Context 'When the tests are negated' { + It 'Should convert `Should -Not -BeIn @(''ExpectedValue1'', ''ExpectedValue2'') ''BecauseString'' ''ActualValue''` correctly' { + InModuleScope -ScriptBlock { + $mockCommandAstPester5 = { + Should -Not -BeIn @('ExpectedValue1', 'ExpectedValue2') 'BecauseString' 'ActualValue' + }.Ast.Find({ $args[0] -is [System.Management.Automation.Language.CommandAst] }, $false) + + $result = Convert-ShouldBeIn -CommandAst $mockCommandAstPester5 + + $result | Should-BeString -CaseSensitive 'Should-NotContainCollection ''ActualValue'' @(''ExpectedValue1'', ''ExpectedValue2'') -Because ''BecauseString''' + } + } + } + + Context 'When tests should always use named parameters' { + It 'Should convert `Should -BeIn @(''ExpectedValue1'', ''ExpectedValue2'') ''BecauseString'' ''ActualValue''` correctly' { + InModuleScope -ScriptBlock { + $mockCommandAstPester5 = { + Should -BeIn @('ExpectedValue1', 'ExpectedValue2') 'BecauseString' 'ActualValue' + }.Ast.Find({ $args[0] -is [System.Management.Automation.Language.CommandAst] }, $false) + + $result = Convert-ShouldBeIn -CommandAst $mockCommandAstPester5 -UseNamedParameters + + $result | Should-BeString -CaseSensitive 'Should-ContainCollection -Actual @(''ExpectedValue1'', ''ExpectedValue2'') -Because ''BecauseString'' -Expected ''ActualValue''' + } + } + + It 'Should convert `''ActualValue'' | Should -BeIn @(''ExpectedValue1'', ''ExpectedValue2'') ''BecauseString''` correctly' { + InModuleScope -ScriptBlock { + $mockCommandAstPester5 = { + 'ActualValue' | Should -BeIn @('ExpectedValue1', 'ExpectedValue2') 'BecauseString' + }.Ast.Find({ $args[0] -is [System.Management.Automation.Language.CommandAst] }, $false) + + $result = Convert-ShouldBeIn -CommandAst $mockCommandAstPester5 -UseNamedParameters + + $result | Should-BeString -CaseSensitive '@(''ExpectedValue1'', ''ExpectedValue2'') | Should-ContainCollection -Because ''BecauseString'' -Expected (''ActualValue'')' + } + } + + It 'Should convert `''ActualValue'' | Get-Something | Should -BeIn @(''ExpectedValue1'', ''ExpectedValue2'') ''BecauseString''` correctly' { + InModuleScope -ScriptBlock { + # Using FindAll() to get the correct AST element we need to pass. + $mockCommandAstPester5 = { + 'ActualValue' | Get-Something | Should -BeIn @('ExpectedValue1', 'ExpectedValue2') 'BecauseString' + }.Ast.FindAll({ $args[0] -is [System.Management.Automation.Language.CommandAst] }, $false) + + $result = Convert-ShouldBeIn -CommandAst $mockCommandAstPester5[1] -UseNamedParameters + + $result | Should-BeString -CaseSensitive '@(''ExpectedValue1'', ''ExpectedValue2'') | Should-ContainCollection -Because ''BecauseString'' -Expected (''ActualValue'' | Get-Something)' + } + } + } + + Context 'When tests should always use positional parameters' { + Context 'When the tests are affirming' { + It 'Should convert `Should -BeIn -ExpectedValue @(''ExpectedValue1'', ''ExpectedValue2'') -Because ''BecauseString'' -ActualValue ''ActualValue''` correctly' { + InModuleScope -ScriptBlock { + $mockCommandAstPester5 = { + Should -BeIn -ExpectedValue @('ExpectedValue1', 'ExpectedValue2') -Because 'BecauseString' -ActualValue 'ActualValue' + }.Ast.Find({ $args[0] -is [System.Management.Automation.Language.CommandAst] }, $false) + + $result = Convert-ShouldBeIn -CommandAst $mockCommandAstPester5 -UsePositionalParameters + + $result | Should-BeString -CaseSensitive 'Should-ContainCollection ''ActualValue'' @(''ExpectedValue1'', ''ExpectedValue2'') -Because ''BecauseString''' + } + } + + It 'Should convert `''ActualValue'' | Should -BeIn -Because ''BecauseString'' -ExpectedValue @(''ExpectedValue1'', ''ExpectedValue2'')` correctly' { + InModuleScope -ScriptBlock { + $mockCommandAstPester5 = { + 'ActualValue' | Should -BeIn -Because 'BecauseString' -ExpectedValue @('ExpectedValue1', 'ExpectedValue2') + }.Ast.Find({ $args[0] -is [System.Management.Automation.Language.CommandAst] }, $false) + + $result = Convert-ShouldBeIn -CommandAst $mockCommandAstPester5 -UsePositionalParameters + + $result | Should-BeString -CaseSensitive '@(''ExpectedValue1'', ''ExpectedValue2'') | Should-ContainCollection (''ActualValue'') -Because ''BecauseString''' + } + } + } + + Context 'When the tests are negated' { + It 'Should convert `Should -Not -BeIn -ExpectedValue @(''ExpectedValue1'', ''ExpectedValue2'') -Because ''BecauseString'' -ActualValue ''ActualValue''` correctly' { + InModuleScope -ScriptBlock { + $mockCommandAstPester5 = { + Should -Not -BeIn -ExpectedValue @('ExpectedValue1', 'ExpectedValue2') -Because 'BecauseString' -ActualValue 'ActualValue' + }.Ast.Find({ $args[0] -is [System.Management.Automation.Language.CommandAst] }, $false) + + $result = Convert-ShouldBeIn -CommandAst $mockCommandAstPester5 -UsePositionalParameters + + $result | Should-BeString -CaseSensitive 'Should-NotContainCollection ''ActualValue'' @(''ExpectedValue1'', ''ExpectedValue2'') -Because ''BecauseString''' + } + } + + It 'Should convert `''ActualValue'' | Should -Not -BeIn -Because ''BecauseString'' -ExpectedValue @(''ExpectedValue1'', ''ExpectedValue2'')` correctly' { + InModuleScope -ScriptBlock { + $mockCommandAstPester5 = { + 'ActualValue' | Should -Not -BeIn -Because 'BecauseString' -ExpectedValue @('ExpectedValue1', 'ExpectedValue2') + }.Ast.Find({ $args[0] -is [System.Management.Automation.Language.CommandAst] }, $false) + + $result = Convert-ShouldBeIn -CommandAst $mockCommandAstPester5 -UsePositionalParameters + + $result | Should-BeString -CaseSensitive '@(''ExpectedValue1'', ''ExpectedValue2'') | Should-NotContainCollection (''ActualValue'') -Because ''BecauseString''' + } + } + } + } + } +} diff --git a/tests/Unit/Private/Get-ShouldThrowScriptBlock.Tests.ps1 b/tests/Unit/Private/Get-PipelineBeforeShould.Tests.ps1 similarity index 86% rename from tests/Unit/Private/Get-ShouldThrowScriptBlock.Tests.ps1 rename to tests/Unit/Private/Get-PipelineBeforeShould.Tests.ps1 index 839c32c..da49abb 100644 --- a/tests/Unit/Private/Get-ShouldThrowScriptBlock.Tests.ps1 +++ b/tests/Unit/Private/Get-PipelineBeforeShould.Tests.ps1 @@ -42,7 +42,7 @@ AfterAll { Get-Module -Name $script:dscModuleName -All | Remove-Module -Force } -Describe 'Get-ShouldThrowScriptBlock' { +Describe 'Get-PipelineBeforeShould' { It 'Should return the correct script block from a parameter' { InModuleScope -ScriptBlock { $mockCommandAst = { @@ -51,7 +51,7 @@ Describe 'Get-ShouldThrowScriptBlock' { } }.Ast.Find({ $args[0] -is [System.Management.Automation.Language.CommandAst] }, $false) - $result = Get-ShouldThrowScriptBlock -CommandAst $mockCommandAst -ParameterName 'ActualValue' -ParsePipeline + $result = Get-PipelineBeforeShould -CommandAst $mockCommandAst -ParameterName 'ActualValue' -ParsePipeline $result | Should-BeString -CaseSensitive "{ Write-Error -Message 'MockErrorMessage' -ErrorId 'MockErrorId' -Category 'InvalidOperation' -TargetObject 'MockTargetObject' -ErrorAction 'Stop' @@ -69,7 +69,7 @@ Describe 'Get-ShouldThrowScriptBlock' { Should -Not -Throw 'MockErrorMessage' -ActualValue $mockScriptBlock }.Ast.Find({ $args[0] -is [System.Management.Automation.Language.CommandAst] }, $false) - $result = Get-ShouldThrowScriptBlock -CommandAst $mockCommandAst -ParameterName 'ActualValue' -ParsePipeline + $result = Get-PipelineBeforeShould -CommandAst $mockCommandAst -ParameterName 'ActualValue' -ParsePipeline $result | Should-BeString -CaseSensitive '$mockScriptBlock' } @@ -83,7 +83,7 @@ Describe 'Get-ShouldThrowScriptBlock' { } | Should -Not -Throw 'MockErrorMessage' }.Ast.Find({ $args[0] -is [System.Management.Automation.Language.CommandAst] }, $false) - $result = Get-ShouldThrowScriptBlock -CommandAst $mockCommandAst -ParameterName 'ActualValue' -ParsePipeline + $result = Get-PipelineBeforeShould -CommandAst $mockCommandAst -ParameterName 'ActualValue' -ParsePipeline $result | Should-BeString -CaseSensitive "{ Write-Error -Message 'MockErrorMessage' -ErrorId 'MockErrorId' -Category 'InvalidOperation' -TargetObject 'MockTargetObject' -ErrorAction 'Stop' @@ -101,7 +101,7 @@ Describe 'Get-ShouldThrowScriptBlock' { $mockScriptBlock | Should -Not -Throw 'MockErrorMessage' }.Ast.Find({ $args[0] -is [System.Management.Automation.Language.CommandAst] }, $false) - $result = Get-ShouldThrowScriptBlock -CommandAst $mockCommandAst -ParameterName 'ActualValue' -ParsePipeline + $result = Get-PipelineBeforeShould -CommandAst $mockCommandAst -ParameterName 'ActualValue' -ParsePipeline $result | Should-BeString -CaseSensitive '$mockScriptBlock' } @@ -113,7 +113,7 @@ Describe 'Get-ShouldThrowScriptBlock' { Get-Something | Get-ScriptBlock | Should -Not -Throw 'MockErrorMessage' }.Ast.Find({ $args[0] -is [System.Management.Automation.Language.CommandAst] }, $false) - $result = Get-ShouldThrowScriptBlock -CommandAst $mockCommandAst -ParameterName 'ActualValue' -ParsePipeline + $result = Get-PipelineBeforeShould -CommandAst $mockCommandAst -ParameterName 'ActualValue' -ParsePipeline $result | Should-BeString -CaseSensitive 'Get-Something | Get-ScriptBlock' } @@ -127,7 +127,7 @@ Describe 'Get-ShouldThrowScriptBlock' { Should -Not -Throw 'MockErrorMessage' }.Ast.Find({ $args[0] -is [System.Management.Automation.Language.CommandAst] }, $false) - $result = Get-ShouldThrowScriptBlock -CommandAst $mockCommandAst -ParameterName 'ActualValue' -ParsePipeline + $result = Get-PipelineBeforeShould -CommandAst $mockCommandAst -ParameterName 'ActualValue' -ParsePipeline $result | Should-BeString -CaseSensitive 'Get-Something | Get-ScriptBlock' @@ -140,7 +140,7 @@ Describe 'Get-ShouldThrowScriptBlock' { Should -Not -Throw }.Ast.Find({ $args[0] -is [System.Management.Automation.Language.CommandAst] }, $false) - $result = Get-ShouldThrowScriptBlock -CommandAst $mockCommandAst -ParameterName 'ActualValue' -ParsePipeline + $result = Get-PipelineBeforeShould -CommandAst $mockCommandAst -ParameterName 'ActualValue' -ParsePipeline $result | Should-BeNull } diff --git a/tests/Unit/Private/Test-IsPipelinePart.tests.ps1 b/tests/Unit/Private/Test-IsPipelinePart.tests.ps1 new file mode 100644 index 0000000..436411a --- /dev/null +++ b/tests/Unit/Private/Test-IsPipelinePart.tests.ps1 @@ -0,0 +1,70 @@ +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')] +param () + +BeforeDiscovery { + try + { + if (-not (Get-Module -Name 'DscResource.Test')) + { + # Assumes dependencies has been resolved, so if this module is not available, run 'noop' task. + if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable)) + { + # Redirect all streams to $null, except the error stream (stream 2) + & "$PSScriptRoot/../../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null + } + + # If the dependencies has not been resolved, this will throw an error. + Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop' + } + } + catch [System.IO.FileNotFoundException] + { + throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.' + } +} + +BeforeAll { + $script:dscModuleName = 'PesterConverter' + + Import-Module -Name $script:dscModuleName + + $PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Mock:ModuleName'] = $script:dscModuleName + $PSDefaultParameterValues['Should:ModuleName'] = $script:dscModuleName +} + +AfterAll { + $PSDefaultParameterValues.Remove('InModuleScope:ModuleName') + $PSDefaultParameterValues.Remove('Mock:ModuleName') + $PSDefaultParameterValues.Remove('Should:ModuleName') + + # Unload the module being tested so that it doesn't impact any other tests. + Get-Module -Name $script:dscModuleName -All | Remove-Module -Force +} + +Describe 'Test-IsPipelinePart' { + It 'Should return $false for a command that is not part of a pipeline' { + InModuleScope -ScriptBlock { + $mockCommandAstPester5 = { + Should -BeIn @('ExpectedValue1', 'ExpectedValue2') 'BecauseString' + }.Ast.FindAll({ $args[0] -is [System.Management.Automation.Language.CommandAst] }, $false) + + $result = Test-IsPipelinePart -CommandAst $mockCommandAstPester5[0] + + $result | Should-BeFalse + } + } + + It 'Should return $true for a command that is part of a pipeline' { + InModuleScope -ScriptBlock { + # Using FindAll() to get the correct AST element we need to pass. + $mockCommandAstPester5 = { + 'ActualValue' | Get-Something | Should -BeIn @('ExpectedValue1', 'ExpectedValue2') 'BecauseString' + }.Ast.FindAll({ $args[0] -is [System.Management.Automation.Language.CommandAst] }, $false) + + $result = Test-IsPipelinePart -CommandAst $mockCommandAstPester5[1] + + $result | Should-BeTrue + } + } +} diff --git a/tests/Unit/Public/Convert-PesterSyntax.tests.ps1 b/tests/Unit/Public/Convert-PesterSyntax.tests.ps1 index 1d792e5..318fc61 100644 --- a/tests/Unit/Public/Convert-PesterSyntax.tests.ps1 +++ b/tests/Unit/Public/Convert-PesterSyntax.tests.ps1 @@ -952,6 +952,123 @@ Describe 'Convert-PesterSyntax' { } } + Context 'When converting Should -BeIn without a pipeline' { + BeforeAll { + $mockAstExtentText = { + Describe 'Should -BeIn' { + It 'Should -BeIn' { + Should -BeIn @('a', 'b') -Because 'BecauseString' -ActualValue $resultValue + } + } + }.Ast.GetScriptBlock().ToString() + + $mockScriptFilePath = Join-Path -Path $TestDrive -ChildPath 'Mock.Tests.ps1' + + Set-Content -Path $mockScriptFilePath -Value $mockAstExtentText -Encoding 'utf8' + } + + It 'Should return the correct converted script' { + $mockExpectedConvertedScript = { + Describe 'Should -BeIn' { + It 'Should -BeIn' { + Should-ContainCollection @('a', 'b') -Because 'BecauseString' -Expected $resultValue + } + } + }.Ast.GetScriptBlock().ToString() + + $result = Convert-PesterSyntax -Path $mockScriptFilePath -PassThru + + $result | Should-BeString -CaseSensitive -Expected $mockExpectedConvertedScript -TrimWhitespace + } + + It 'Should return the correct converted script using named parameters' { + $mockExpectedConvertedScript = { + Describe 'Should -BeIn' { + It 'Should -BeIn' { + Should-ContainCollection -Actual @('a', 'b') -Because 'BecauseString' -Expected $resultValue + } + } + }.Ast.GetScriptBlock().ToString() + + $result = Convert-PesterSyntax -Path $mockScriptFilePath -UseNamedParameters -PassThru + + $result | Should-BeString -CaseSensitive -Expected $mockExpectedConvertedScript -TrimWhitespace + } + + It 'Should return the correct converted script using positional parameters' { + $mockExpectedConvertedScript = { + Describe 'Should -BeIn' { + It 'Should -BeIn' { + Should-ContainCollection $resultValue @('a', 'b') -Because 'BecauseString' + } + } + }.Ast.GetScriptBlock().ToString() + + $result = Convert-PesterSyntax -Path $mockScriptFilePath -UsePositionalParameters -PassThru + + $result | Should-BeString -CaseSensitive -Expected $mockExpectedConvertedScript -TrimWhitespace + } + } + + Context 'When converting Should -BeIn with a pipeline' { + BeforeAll { + $mockAstExtentText = { + Describe 'Should -BeIn' { + It 'Should -BeIn' { + $resultValue | Get-Something | Should -BeIn @('a', 'b') -Because 'BecauseString' + } + } + }.Ast.GetScriptBlock().ToString() + + $mockScriptFilePath = Join-Path -Path $TestDrive -ChildPath 'Mock.Tests.ps1' + + Set-Content -Path $mockScriptFilePath -Value $mockAstExtentText -Encoding 'utf8' + } + + It 'Should return the correct converted script' { + $mockExpectedConvertedScript = { + + Describe 'Should -BeIn' { + It 'Should -BeIn' { + @('a', 'b') | Should-ContainCollection ($resultValue | Get-Something) -Because 'BecauseString' + } + } + }.Ast.GetScriptBlock().ToString() + + $result = Convert-PesterSyntax -Path $mockScriptFilePath -PassThru + + $result | Should-BeString -CaseSensitive -Expected $mockExpectedConvertedScript -TrimWhitespace + } + + It 'Should return the correct converted script using named parameters' { + $mockExpectedConvertedScript = { + Describe 'Should -BeIn' { + It 'Should -BeIn' { + @('a', 'b') | Should-ContainCollection -Because 'BecauseString' -Expected ($resultValue | Get-Something) + } + } + }.Ast.GetScriptBlock().ToString() + + $result = Convert-PesterSyntax -Path $mockScriptFilePath -UseNamedParameters -PassThru + + $result | Should-BeString -CaseSensitive -Expected $mockExpectedConvertedScript -TrimWhitespace + } + + It 'Should return the correct converted script using positional parameters' { + $mockExpectedConvertedScript = { + Describe 'Should -BeIn' { + It 'Should -BeIn' { + @('a', 'b') | Should-ContainCollection ($resultValue | Get-Something) -Because 'BecauseString' + } + } + }.Ast.GetScriptBlock().ToString() + + $result = Convert-PesterSyntax -Path $mockScriptFilePath -UsePositionalParameters -PassThru + + $result | Should-BeString -CaseSensitive -Expected $mockExpectedConvertedScript -TrimWhitespace + } + } + Context 'When converting several files' { BeforeAll { $mockAstExtentText = {