Closed vors closed 7 years ago
Same on eaf270ab3f7620fe47e5470ca14afab25a8c5a9b (master)
It's a pipeline, this works fine
Describe "Pester shoud understand arrays" {
It "two arrays are different" {
@(, @(1)) | Should not be @(, @(1,2))
}
}
I'm still not satisfied:
Describe "Pester shoud understand arrays" {
It "Arrays should be the same" {
@(, @(1, 2)) | Should be @(, @(1, 2))
}
}
I started looking into this several months ago, but ran into some annoying headaches and threw out the code. Here's what I remember about it:
Once those design questions are sorted out, the coding itself isn't too hard. The only thing that we can't solve without a breaking change would be the quirks related to using a pipeline, and those can be solved by the caller if they simply use a unary comma (or Write-Output -NoEnumerate) before piping to Should. For example:
,$array1 | Should Be $array2
Another option would be to make a command that doesn't involve the pipe, something like
Assert $array1 Should Be $array2
I forgot that PowerShell treat -eq
as filter operation for arrays
@('x') -eq @('x')
x
I suppose we can start with a fairly simple approach:
Sound like a plan? If so, I basically already did that work (and I may still have that old branch lying around somewhere.) The only annoying quirk that I can remember was this:
$null | Should Be @()
@() | Should Be $null
Both of those tests would succeed, because there was no way for the method to know whether the original input was an empty array or $null. However, that's an edge case that's not really that big of a deal (other than annoying me.)
This is something we can include in v4. It's technically a breaking change, though it's probably unlikely that anyone is depending on the old behavior of -eq and collections.
That sounds perfect for me.
I hit the same wall with arrays today and I think it's a wonderful idea to support it.
I've come up with a simple solution that works quite well for my context (thought probably not elegant enough) to compare two arrays regardless of their order.
function Assert-ArrayEquals { param($array, $expected) for($i = 0; $i -lt $expected.length; $i++){ $expected -contains $array[$i] | Should Be $true } }
The only problem is that it isn't quite verbose enough (Only return "expected : true but was false") but I think it's solvable without affecting performance.
Hope that helps others !
FOLLOW-UP : I ended up adding "MatchArray" in the assertions which does exactly the same as my code above. And now this works :
@("1","2") | Should MatchArray @("2","1")
And it wouldn't be hard to do a MatchArrayWithOrder or something like that.
Please check @stuartleeks projects
More Pester's related links on my blog -> https://blog.it-praktyk.pl/2016/05/29/Pester-related-links/
Stumbled upon this too and tried to use the suggested solution with PesterMatchArray
, but it doesn't test the content deeply enough . So in the end I reverted to this post and used the following test:
$Result = @(
[PSCustomObject]@{
'First Name' = 'Chuck'
'Address' = 'California'
}
[PSCustomObject]@{
'First Name' = 'Jean-Claude'
'Address' = 'Brussels'
}
)
$ExpectedResult = @"
[
{
"First Name": "Chuck",
"Address": "California"
},
{
"First Name": "Jean-Claude",
"Address": "Brussels"
}
]
"@
[String]::Compare(($Result | ConvertTo-Json),$ExpectedResult) | Should Be 0
Maybe this could help you: https://github.com/nohwnd/Assert#comparing-whole-objects
Perfect! Even better! Thank you very much for the helpful module. Love it already! Only thing missing is case sensitivity, but that's just nitpicking.
I assume that the issue can be closed soon (7 days). Feel free to send any additional information that can be helpful to answer your question/issue.
Would be nice if Pester itself provides such a functionality without installing other modules like the mentioned one from @stuartleeks
I would love that!
Thanks, Patrick
Not a solution, but a workaround. The way that I'm working around this issue is by gathering the results into a variable and then doing multiple Should(s). Like so:
It 'GetCsvKvp returns correct KVP array from a CsvString with correctly formatted CSV and valid KVP (key value pair)' { $KvpArray = GetCsvKvp -CsvString 'this=that,those=them' $KvpArray | Should -HaveCount 2 ($KvpArray | where {$_.Name -eq 'this'} ).Value | Should -Be 'that' ($KvpArray | where {$_.Name -eq 'those'} ).Value | Should -Be 'them' }
Works great for small scenarios. Hope this helps someone.
Jim Roberts
I just hit this as well. I tried the below, worked for me. I created a little helper function to re-order the array if the contents matched.
function Convert-ArrayOrderToSource {
param (
[parameter(mandatory=$true)]
[array]$SourceArray,
[parameter(mandatory=$true)]
[array]$DifferenceArray
)
if(!(Compare-Object -ReferenceObject $a -DifferenceObject $b)) {
$result = $SourceArray
}
else {
$result = $DifferenceArray
}
return $result
}
Then in my pester test I convert the array. If it doesn't match it just spits out the original array and will fail the test.
$propertiesInOrder | Should -Be $expectedProperties
This test fails on a4244c3c3825f4a108be5283a98bb6eb7a3e3508 (v4 branch)