Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions src/functions/assertions/Be.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ function ShouldBeFailureMessage($ActualValue, $ExpectedValue, $Because) {
if ($actualLength -ne $expectedLength) {
return "Expected a collection $(Format-Nicely $ExpectedValue) with length $expectedLength,$(if ($null -ne $Because) { Format-Because $Because }) but got a collection $(Format-Nicely $ActualValue) with length $actualLength."
}

$differenceIndex = Get-CollectionDifferenceIndex -ActualValue @($ActualValue) -ExpectedValue @($ExpectedValue)
if ($null -ne $differenceIndex) {
return (Get-CompareCollectionMessage -ActualValue @($ActualValue) -ExpectedValue @($ExpectedValue) -DifferenceIndex $differenceIndex -Because $Because) -join "`n"
}
}

# This looks odd; it's to unroll single-element arrays so the "-is [string]" expression works properly.
Expand Down Expand Up @@ -141,6 +146,21 @@ function Should-BeAssertionExactly($ActualValue, $ExpectedValue, $Because) {
}

function ShouldBeExactlyFailureMessage($ActualValue, $ExpectedValue, $Because) {
$actualIsCollection = $ActualValue -is [System.Collections.IEnumerable] -and $ActualValue -isnot [string]
$expectedIsCollection = $ExpectedValue -is [System.Collections.IEnumerable] -and $ExpectedValue -isnot [string]

if ($actualIsCollection -and $expectedIsCollection) {
$actualLength = @($ActualValue).Count
$expectedLength = @($ExpectedValue).Count

if ($actualLength -eq $expectedLength) {
$differenceIndex = Get-CollectionDifferenceIndex -ActualValue @($ActualValue) -ExpectedValue @($ExpectedValue) -CaseSensitive
if ($null -ne $differenceIndex) {
return (Get-CompareCollectionMessage -ActualValue @($ActualValue) -ExpectedValue @($ExpectedValue) -DifferenceIndex $differenceIndex -Because $Because) -join "`n"
}
}
}

# This looks odd; it's to unroll single-element arrays so the "-is [string]" expression works properly.
$ActualValue = $($ActualValue)
$ExpectedValue = $($ExpectedValue)
Expand Down Expand Up @@ -245,6 +265,49 @@ function Get-CompareStringMessage {
}
}

function Get-CollectionDifferenceIndex {
param(
[object[]] $ActualValue,
[object[]] $ExpectedValue,
[switch] $CaseSensitive
)

for ($i = 0; $i -lt $ExpectedValue.Count; $i++) {
if ((IsArray $ActualValue[$i]) -or (IsArray $ExpectedValue[$i])) {
if (-not (ArraysAreEqual -First $ActualValue[$i] -Second $ExpectedValue[$i] -CaseSensitive:$CaseSensitive)) {
return $i
}
}
else {
if ($CaseSensitive) {
$comparer = { param($Actual, $Expected) $Expected -ceq $Actual }
}
else {
$comparer = { param($Actual, $Expected) $Expected -eq $Actual }
}

if (-not (& $comparer $ActualValue[$i] $ExpectedValue[$i])) {
return $i
}
}
}
}

function Get-CompareCollectionMessage {
param(
[object[]] $ExpectedValue,
[object[]] $ActualValue,
[int] $DifferenceIndex,
$Because
)

"Expected collections to be the same,$(if ($null -ne $Because) { Format-Because $Because }) but they were different."
"Collection lengths are both $($ExpectedValue.Count)."
"Collections differ at index $DifferenceIndex."
"Expected: $(Format-Nicely $ExpectedValue)"
"But was: $(Format-Nicely $ActualValue)"
}

function Format-AsExcerpt {
param (
[Parameter(Mandatory = $true)]
Expand Down
12 changes: 10 additions & 2 deletions tst/functions/assertions/Be.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ InPesterModuleScope {
$array | Should -EQ $array
}

It 'Passes for equal arrays with the same length' {
@(1, 2, 3) | Should -Be @(1, 2, 3)
}

It 'Compares arrays with correct case-insensitive behavior' {
$string = 'I am a string'
$array = @(1, 2, 3, 4, $string)
Expand Down Expand Up @@ -146,8 +150,8 @@ InPesterModuleScope {
ShouldBeFailureMessage (, (1, 2, 3)) (1, 2, 3) -Because 'reason' | Verify-Equal "Expected a collection @(1, 2, 3) with length 3, because reason, but got a collection @(@(1, 2, 3)) with length 1."
}

It "Keeps the plain message for collections of equal length" {
ShouldBeFailureMessage (1, 2, 3) (1, 2, 4) | Verify-Equal "Expected @(1, 2, 4), but got @(1, 2, 3)."
It "Outputs the differing index for collections of equal length" {
ShouldBeFailureMessage (1, 2, 3) (1, 2, 4) | Verify-Equal "Expected collections to be the same, but they were different.`nCollection lengths are both 3.`nCollections differ at index 2.`nExpected: @(1, 2, 4)`nBut was: @(1, 2, 3)"
}

It "Outputs verbose message for two strings of different length" {
Expand Down Expand Up @@ -209,6 +213,10 @@ InPesterModuleScope {
It "Writes verbose message for strings that differ by case" {
ShouldBeExactlyFailureMessage "a" "A" -Because "reason" | Verify-Equal "Expected strings to be the same, because reason, but they were different.`nString lengths are both 1.`nStrings differ at index 0.`nExpected: 'A'`nBut was: 'a'`n ^"
}

It "Outputs the differing index for collections of equal length" {
ShouldBeExactlyFailureMessage ('a', 'b') ('a', 'B') | Verify-Equal "Expected collections to be the same, but they were different.`nCollection lengths are both 2.`nCollections differ at index 1.`nExpected: @('a', 'B')`nBut was: @('a', 'b')"
}
}
}

Expand Down
Loading