Skip to content

Commit e70b372

Browse files
nohwndCopilot
andauthored
Apply value-assertion rules consistently to Should-* siblings (#2707)
The Pester 6 assertion rules in docs/assertion-types.md say generic value assertions reject collections on -Expected, and value assertions unwrap pipeline input via Collect-Input -UnrollInput. A handful of Should-* didn't follow either rule, behaving differently from their siblings: - Should-NotBeString: missing Collect-Input. Multi-item pipeline silently used the last item; non-string Actual silently passed the assertion. Now mirrors Should-NotBeLikeString and throws ArgumentException when Actual isn't a string. - Should-BeAfter / Should-BeBefore: missing Collect-Input. Also missing the -Because parameter declaration entirely, so the documented switch was a no-op. Both fixed. - Should-BeSame / Should-NotBeSame: missing Ensure-ExpectedIsNotCollection, so passing @() to -Expected produced a misleading "not the same instance" failure instead of the standard collection-on-Expected error. Tests added to lock in each rule. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent ce93186 commit e70b372

10 files changed

Lines changed: 68 additions & 2 deletions

File tree

src/functions/assert/General/Should-BeSame.ps1

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@
4747
[String]$Because
4848
)
4949

50+
$null = Ensure-ExpectedIsNotCollection $Expected
51+
5052
if ($Expected -is [ValueType] -or $Expected -is [string]) {
5153
throw [ArgumentException]"Should-BeSame compares objects by reference. You provided a value type or a string, those are not reference types and you most likely don't need to compare them by reference, see https://github.com/nohwnd/Assert/issues/6.`n`nAre you trying to compare two values to see if they are equal? Use Should-BeEqual instead."
5254
}

src/functions/assert/General/Should-NotBeSame.ps1

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@
4646
[String]$Because
4747
)
4848

49+
$null = Ensure-ExpectedIsNotCollection $Expected
50+
4951
$collectedInput = Collect-Input -ParameterInput $Actual -PipelineInput $local:Input -IsPipelineInput $MyInvocation.ExpectingInput -UnrollInput
5052
$Actual = $collectedInput.Actual
5153
if ([object]::ReferenceEquals($Expected, $Actual)) {

src/functions/assert/String/Should-NotBeString.ps1

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@ function Should-NotBeString {
5959
[switch]$IgnoreWhitespace
6060
)
6161

62+
$collectedInput = Collect-Input -ParameterInput $Actual -PipelineInput $local:Input -IsPipelineInput $MyInvocation.ExpectingInput -UnrollInput
63+
$Actual = $collectedInput.Actual
64+
65+
if ($Actual -isnot [string]) {
66+
throw [ArgumentException]"Actual is expected to be string, to avoid confusing behavior that -ne operator exhibits with collections. To assert on collections use Should-Any, Should-All or some other collection assertion."
67+
}
68+
6269
if (Test-StringEqual -Expected $Expected -Actual $Actual -CaseSensitive:$CaseSensitive -IgnoreWhitespace:$IgnoreWhiteSpace) {
6370
if (-not $CustomMessage) {
6471
$formattedMessage = Get-StringNotEqualDefaultFailureMessage -Expected $Expected -Actual $Actual

src/functions/assert/Time/Should-BeAfter.ps1

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,14 @@
8080
[switch] $FromNow,
8181

8282
[Parameter(Position = 0, ParameterSetName = "Expected")]
83-
[DateTime] $Expected
83+
[DateTime] $Expected,
84+
85+
[String] $Because
8486
)
8587

88+
$collectedInput = Collect-Input -ParameterInput $Actual -PipelineInput $local:Input -IsPipelineInput $MyInvocation.ExpectingInput -UnrollInput
89+
$Actual = $collectedInput.Actual
90+
8691
# Now is just a syntax marker, we don't need to do anything with it.
8792
$Now = $Now
8893

src/functions/assert/Time/Should-BeBefore.ps1

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,14 @@
8080
[switch] $FromNow,
8181

8282
[Parameter(Position = 0, ParameterSetName = "Expected")]
83-
[DateTime] $Expected
83+
[DateTime] $Expected,
84+
85+
[String] $Because
8486
)
8587

88+
$collectedInput = Collect-Input -ParameterInput $Actual -PipelineInput $local:Input -IsPipelineInput $MyInvocation.ExpectingInput -UnrollInput
89+
$Actual = $collectedInput.Actual
90+
8691
# Now is just a syntax marker, we don't need to do anything with it.
8792
$Now = $Now
8893

tst/functions/assert/General/Should-BeSame.Tests.ps1

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,9 @@ Describe "Should-BeSame" {
4242
$object = New-Object Diagnostics.Process
4343
{ Should-BeSame $object "abc" } | Verify-AssertionFailed
4444
}
45+
46+
It "Throws when collection is passed to -Expected" {
47+
$err = { "dummy" | Should-BeSame -Expected @() } | Verify-Throw
48+
$err.Exception | Verify-Type ([ArgumentException])
49+
}
4550
}

tst/functions/assert/General/Should-NotBeSame.Tests.ps1

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,13 @@ Describe "Should-NotBeSame" {
3030
Should-NotBeSame $obj $obj
3131
} | Verify-AssertionFailed
3232
}
33+
34+
It "Throws when collection is passed to -Expected" {
35+
$err = {
36+
$obj = New-Object -TypeName PSObject
37+
$obj | Should-NotBeSame -Expected @()
38+
} | Verify-Throw
39+
$err.Exception | Verify-Type ([ArgumentException])
40+
}
3341
}
3442

tst/functions/assert/String/Should-NotBeString.Tests.ps1

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,5 +50,15 @@ Describe "Should-NotBeString" {
5050
It "Can be called with positional parameters" {
5151
{ Should-NotBeString "a" "a" } | Verify-AssertionFailed
5252
}
53+
54+
It "Throws when collection of strings is passed in by pipeline, even if the last string is different from the expected string" {
55+
$err = { "abc", "bde" | Should-NotBeString -Expected "abc" } | Verify-Throw
56+
$err.Exception | Verify-Type ([ArgumentException])
57+
}
58+
59+
It "Throws when -Actual is not a string" {
60+
$err = { Should-NotBeString -Expected "abc" -Actual 1 } | Verify-Throw
61+
$err.Exception | Verify-Type ([ArgumentException])
62+
}
5363
}
5464

tst/functions/assert/Time/Should-BeAfter.Tests.ps1

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,17 @@ Describe "Should-BeAfter" {
4949
{ $Actual | Should-BeAfter 10minutes -Ago -FromNow } | Verify-Throw
5050
}
5151

52+
It "Fails for array input even if the last item is after the expected date" {
53+
$past = [DateTime]::Now.AddDays(-1)
54+
$future = [DateTime]::Now.AddDays(1)
55+
{ $past, $future | Should-BeAfter -Expected ([DateTime]::Now) } | Verify-AssertionFailed
56+
}
57+
58+
It "Has Because parameter" {
59+
$err = { [DateTime]::Now.AddDays(-1) | Should-BeAfter -Expected ([DateTime]::Now) -Because 'I said so' } | Verify-AssertionFailed
60+
$err.Exception.Message | Verify-Like '*because I said so*'
61+
}
62+
5263
It "Can check file creation date" {
5364
New-Item -ItemType Directory -Path "TestDrive:\MyFolder" -Force | Out-Null
5465
$path = "TestDrive:\MyFolder\test.txt"

tst/functions/assert/Time/Should-BeBefore.Tests.ps1

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,17 @@ Describe "Should-BeBefore" {
4949
{ $Actual | Should-BeBefore 10minutes -Ago -FromNow } | Verify-Throw
5050
}
5151

52+
It "Fails for array input even if the last item is before the expected date" {
53+
$past = [DateTime]::Now.AddDays(-1)
54+
$future = [DateTime]::Now.AddDays(1)
55+
{ $future, $past | Should-BeBefore -Expected ([DateTime]::Now) } | Verify-AssertionFailed
56+
}
57+
58+
It "Has Because parameter" {
59+
$err = { [DateTime]::Now.AddDays(1) | Should-BeBefore -Expected ([DateTime]::Now) -Because 'I said so' } | Verify-AssertionFailed
60+
$err.Exception.Message | Verify-Like '*because I said so*'
61+
}
62+
5263
It "Can check file creation date" {
5364
New-Item -ItemType Directory -Path "TestDrive:\MyFolder" -Force | Out-Null
5465
$path = "TestDrive:\MyFolder\test.txt"

0 commit comments

Comments
 (0)