Skip to content

Commit

Permalink
Fix collecting from pipeline
Browse files Browse the repository at this point in the history
  • Loading branch information
nohwnd committed Apr 6, 2024
1 parent 0bf4752 commit b54b003
Show file tree
Hide file tree
Showing 25 changed files with 65 additions and 107 deletions.
3 changes: 2 additions & 1 deletion src/functions/assert/Boolean/Assert-False.ps1
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
function Assert-False {
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseProcessBlockForPipelineCommand', '')]
param (
[Parameter(ValueFromPipeline=$true)]
$Actual,
[String]$CustomMessage
)

$Actual = Collect-Input -ParameterInput $Actual -PipelineInput $local:Input
$Actual = Collect-Input -ParameterInput $Actual -PipelineInput $local:Input -IsInPipeline $MyInvocation.ExpectingInput
if ($Actual)
{
$Message = Get-AssertionMessage -Expected $false -Actual $Actual -CustomMessage $CustomMessage -DefaultMessage "Expected <actualType> '<actual>' to be <expectedType> '<expected>' or falsy value 0, """", `$null, @()."
Expand Down
10 changes: 5 additions & 5 deletions src/functions/assert/Boolean/Assert-True.ps1
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
function Assert-True{
function Assert-True {
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseProcessBlockForPipelineCommand', '')]
param (
[Parameter(ValueFromPipeline=$true)]
[Parameter(ValueFromPipeline = $true)]
$Actual,
[String]$CustomMessage
)

$Actual = Collect-Input -ParameterInput $Actual -PipelineInput $local:Input
if (-not $Actual)
{
$Actual = Collect-Input -ParameterInput $Actual -PipelineInput $local:Input -IsInPipeline $MyInvocation.ExpectingInput
if (-not $Actual) {
$Message = Get-AssertionMessage -Expected $true -Actual $Actual -CustomMessage $CustomMessage -DefaultMessage "Expected <actualType> '<actual>' to be <expectedType> '<expected>' or truthy value."
throw [Pester.Factory]::CreateShouldErrorRecord($Message, $MyInvocation.ScriptName, $MyInvocation.ScriptLineNumber, $MyInvocation.Line.TrimEnd([System.Environment]::NewLine), $true)
}
Expand Down
3 changes: 2 additions & 1 deletion src/functions/assert/Collection/Assert-All.ps1
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
function Assert-All {
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseProcessBlockForPipelineCommand', '')]
[CmdletBinding()]
param (
[Parameter(ValueFromPipeline = $true, Position = 1)]
Expand All @@ -10,7 +11,7 @@


$Expected = $FilterScript
$Actual = Collect-Input -ParameterInput $Actual -PipelineInput $local:Input
$Actual = Collect-Input -ParameterInput $Actual -PipelineInput $local:Input -IsInPipeline $MyInvocation.ExpectingInput
# we are jumping between modules so I need to explicitly pass the _ variable
# simply using '&' won't work
# see: https://blogs.msdn.microsoft.com/sergey_babkins_blog/2014/10/30/calling-the-script-blocks-in-powershell/
Expand Down
3 changes: 2 additions & 1 deletion src/functions/assert/Collection/Assert-Any.ps1
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
function Assert-Any {
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseProcessBlockForPipelineCommand', '')]
param (
[Parameter(ValueFromPipeline = $true, Position = 1)]
$Actual,
Expand All @@ -8,7 +9,7 @@
)

$Expected = $FilterScript
$Actual = Collect-Input -ParameterInput $Actual -PipelineInput $local:Input
$Actual = Collect-Input -ParameterInput $Actual -PipelineInput $local:Input -IsInPipeline $MyInvocation.ExpectingInput
if (-not ($Actual | & $SafeCommands['Where-Object'] -FilterScript $FilterScript)) {

Check notice

Code scanning / PSScriptAnalyzer

The built-in *-Object-cmdlets are slow compared to alternatives in .NET. To fix a violation of this rule, consider using an alternative like foreach/for-keyword etc.`. Note

The built-in *-Object-cmdlets are slow compared to alternatives in .NET. To fix a violation of this rule, consider using an alternative like foreach/for-keyword etc.`.
$Message = Get-AssertionMessage -Expected $Expected -Actual $Actual -CustomMessage $CustomMessage -DefaultMessage "Expected at least one item in collection '<actual>' to pass filter '<expected>', but none of the items passed the filter."
throw [Pester.Factory]::CreateShouldErrorRecord($Message, $MyInvocation.ScriptName, $MyInvocation.ScriptLineNumber, $MyInvocation.Line.TrimEnd([System.Environment]::NewLine), $true)
Expand Down
3 changes: 2 additions & 1 deletion src/functions/assert/Collection/Assert-Contain.ps1
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
function Assert-Contain {
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseProcessBlockForPipelineCommand', '')]
param (
[Parameter(Position=1, ValueFromPipeline=$true)]
$Actual,
Expand All @@ -7,7 +8,7 @@
[String]$CustomMessage
)

$Actual = Collect-Input -ParameterInput $Actual -PipelineInput $local:Input
$Actual = Collect-Input -ParameterInput $Actual -PipelineInput $local:Input -IsInPipeline $MyInvocation.ExpectingInput
if ($Actual -notcontains $Expected)
{
$type = [string]$Expected

Check warning

Code scanning / PSScriptAnalyzer

The variable 'type' is assigned but never used. Warning

The variable 'type' is assigned but never used.
Expand Down
3 changes: 2 additions & 1 deletion src/functions/assert/Collection/Assert-NotContain.ps1
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
function Assert-NotContain {
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseProcessBlockForPipelineCommand', '')]
param (
[Parameter(Position=1, ValueFromPipeline=$true)]
$Actual,
Expand All @@ -7,7 +8,7 @@
[String]$CustomMessage
)

$Actual = Collect-Input -ParameterInput $Actual -PipelineInput $local:Input
$Actual = Collect-Input -ParameterInput $Actual -PipelineInput $local:Input -IsInPipeline $MyInvocation.ExpectingInput
if ($Actual -contains $Expected)
{
$type = [string]$Expected

Check warning

Code scanning / PSScriptAnalyzer

The variable 'type' is assigned but never used. Warning

The variable 'type' is assigned but never used.
Expand Down
16 changes: 5 additions & 11 deletions src/functions/assert/Common/Collect-Input.ps1
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
function Collect-Input ($ParameterInput, $PipelineInput)
{
#source: http://www.powertheshell.com/input_psv3/
$collectedInput = @($PipelineInput)

$isInPipeline = $collectedInput.Count -gt 0
if ($isInPipeline) {
$collectedInput
function Collect-Input ($ParameterInput, $PipelineInput, $IsInPipeline) {
if ($IsInPipeline) {
$PipelineInput
}
else
{
else {
$ParameterInput
}
}
}
53 changes: 0 additions & 53 deletions src/functions/assert/Compatibility.ps1
Original file line number Diff line number Diff line change
@@ -1,57 +1,4 @@


function Invoke-WithContext {
param(
[Parameter(Mandatory = $true )]
[ScriptBlock] $ScriptBlock,
[Parameter(Mandatory = $true)]
[hashtable] $Variables)

# this functions is a psv2 compatible version of
# ScriptBlock InvokeWithContext that is not available
# in that version of PowerShell

# this is what the code below does
# which in effect sets the context without detaching the
# scriptblock from the original scope
# & {
# # context
# $a = 10
# $b = 20
# # invoking our original scriptblock
# & $sb
# }

# a similar solution was $SessionState.PSVariable.Set('a', 10)
# but that sets the variable for all "scopes" in the current
# scope so the value persist after the original has run which
# is not correct,

$scriptBlockWithContext = {
param($context)

foreach ($pair in $context.Variables.GetEnumerator()) {
New-Variable -Name $pair.Key -Value $pair.Value
}

# this cleans up the variable from the session
# the subexpression outputs the value of the variable
# and then deletes the variable, so the value is still passed
# but the variable no longer exists when the scriptblock executes
& $($context.ScriptBlock; Remove-Variable -Name 'context' -Scope Local)
}

$flags = [System.Reflection.BindingFlags]'Instance,NonPublic'
$SessionState = $ScriptBlock.GetType().GetProperty("SessionState", $flags).GetValue($ScriptBlock, $null)
$SessionStateInternal = $SessionState.GetType().GetProperty('Internal', $flags).GetValue($SessionState, $null)

# attach the original session state to the wrapper scriptblock
# making it invoke in the same scope as $ScriptBlock
$scriptBlockWithContext.GetType().GetProperty('SessionStateInternal', $flags).SetValue($scriptBlockWithContext, $SessionStateInternal, $null)

& $scriptBlockWithContext @{ ScriptBlock = $ScriptBlock; Variables = $Variables }
}

function Test-NullOrWhiteSpace ($Value) {
# psv2 compatibility, on newer .net we would simply use
# [string]::isnullorwhitespace
Expand Down
3 changes: 2 additions & 1 deletion src/functions/assert/Exception/Assert-Throw.ps1
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
function Assert-Throw {
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseProcessBlockForPipelineCommand', '')]
param (
[Parameter(ValueFromPipeline = $true, Mandatory = $true)]
[ScriptBlock]$ScriptBlock,
Expand All @@ -9,7 +10,7 @@ function Assert-Throw {
[String]$CustomMessage
)

$ScriptBlock = Collect-Input -ParameterInput $ScriptBlock -PipelineInput $local:Input
$ScriptBlock = Collect-Input -ParameterInput $ScriptBlock -PipelineInput $local:Input -IsInPipeline $MyInvocation.ExpectingInput

$errorThrown = $false
$err = $null
Expand Down
10 changes: 5 additions & 5 deletions src/functions/assert/General/Assert-Equal.ps1
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
function Assert-Equal {
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseProcessBlockForPipelineCommand', '')]
param (
[Parameter(Position=1, ValueFromPipeline=$true)]
[Parameter(Position = 1, ValueFromPipeline = $true)]
$Actual,
[Parameter(Position=0)]
[Parameter(Position = 0)]
$Expected,
[String]$CustomMessage
)

$Actual = Collect-Input -ParameterInput $Actual -PipelineInput $local:Input
$Actual = Collect-Input -ParameterInput $Actual -PipelineInput $local:Input -IsInPipeline $MyInvocation.ExpectingInput

if ((Ensure-ExpectedIsNotCollection $Expected) -ne $Actual)
{
if ((Ensure-ExpectedIsNotCollection $Expected) -ne $Actual) {
$Message = Get-AssertionMessage -Expected $Expected -Actual $Actual -CustomMessage $CustomMessage -DefaultMessage "Expected <expectedType> '<expected>', but got <actualType> '<actual>'."
throw [Pester.Factory]::CreateShouldErrorRecord($Message, $MyInvocation.ScriptName, $MyInvocation.ScriptLineNumber, $MyInvocation.Line.TrimEnd([System.Environment]::NewLine), $true)
}
Expand Down
3 changes: 2 additions & 1 deletion src/functions/assert/General/Assert-GreaterThan.ps1
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
function Assert-GreaterThan {
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseProcessBlockForPipelineCommand', '')]
param (
[Parameter(Position=1, ValueFromPipeline=$true)]
$Actual,
Expand All @@ -7,7 +8,7 @@
[String]$CustomMessage
)

$Actual = Collect-Input -ParameterInput $Actual -PipelineInput $local:Input
$Actual = Collect-Input -ParameterInput $Actual -PipelineInput $local:Input -IsInPipeline $MyInvocation.ExpectingInput
if ((Ensure-ExpectedIsNotCollection $Expected) -ge $Actual)
{
$Message = Get-AssertionMessage -Expected $Expected -Actual $Actual -CustomMessage $CustomMessage -DefaultMessage "Expected <actualType> '<actual>' to be greater than <expectedType> '<expected>', but it was not."
Expand Down
3 changes: 2 additions & 1 deletion src/functions/assert/General/Assert-GreaterThanOrEqual.ps1
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
function Assert-GreaterThanOrEqual {
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseProcessBlockForPipelineCommand', '')]
param (
[Parameter(Position=1, ValueFromPipeline=$true)]
$Actual,
Expand All @@ -7,7 +8,7 @@
[String]$CustomMessage
)

$Actual = Collect-Input -ParameterInput $Actual -PipelineInput $local:Input
$Actual = Collect-Input -ParameterInput $Actual -PipelineInput $local:Input -IsInPipeline $MyInvocation.ExpectingInput
if ((Ensure-ExpectedIsNotCollection $Expected) -gt $Actual)
{
$Message = Get-AssertionMessage -Expected $Expected -Actual $Actual -CustomMessage $CustomMessage -DefaultMessage "Expected <actualType> '<actual>' to be greater than or equal to <expectedType> '<expected>', but it was not."
Expand Down
3 changes: 2 additions & 1 deletion src/functions/assert/General/Assert-LessThan.ps1
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
function Assert-LessThan {
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseProcessBlockForPipelineCommand', '')]
param (
[Parameter(Position=1, ValueFromPipeline=$true)]
$Actual,
Expand All @@ -7,7 +8,7 @@
[String]$CustomMessage
)

$Actual = Collect-Input -ParameterInput $Actual -PipelineInput $local:Input
$Actual = Collect-Input -ParameterInput $Actual -PipelineInput $local:Input -IsInPipeline $MyInvocation.ExpectingInput
if ((Ensure-ExpectedIsNotCollection $Expected) -le $Actual)
{
$Message = Get-AssertionMessage -Expected $Expected -Actual $Actual -CustomMessage $CustomMessage -DefaultMessage "Expected <actualType> '<actual>' to be less than <expectedType> '<expected>', but it was not."
Expand Down
3 changes: 2 additions & 1 deletion src/functions/assert/General/Assert-LessThanOrEqual.ps1
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
function Assert-LessThanOrEqual {
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseProcessBlockForPipelineCommand', '')]
param (
[Parameter(Position=1, ValueFromPipeline=$true)]
$Actual,
Expand All @@ -7,7 +8,7 @@
[String]$CustomMessage
)

$Actual = Collect-Input -ParameterInput $Actual -PipelineInput $local:Input
$Actual = Collect-Input -ParameterInput $Actual -PipelineInput $local:Input -IsInPipeline $MyInvocation.ExpectingInput
if ((Ensure-ExpectedIsNotCollection $Expected) -lt $Actual)
{
$Message = Get-AssertionMessage -Expected $Expected -Actual $Actual -CustomMessage $CustomMessage -DefaultMessage "Expected <actualType> '<actual>' to be less than or equal to <expectedType> '<expected>', but it was not."
Expand Down
3 changes: 2 additions & 1 deletion src/functions/assert/General/Assert-NotEqual.ps1
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
function Assert-NotEqual {
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseProcessBlockForPipelineCommand', '')]
param (
[Parameter(Position=1, ValueFromPipeline=$true)]
$Actual,
Expand All @@ -7,7 +8,7 @@
[String]$CustomMessage
)

$Actual = Collect-Input -ParameterInput $Actual -PipelineInput $local:Input
$Actual = Collect-Input -ParameterInput $Actual -PipelineInput $local:Input -IsInPipeline $MyInvocation.ExpectingInput
if ((Ensure-ExpectedIsNotCollection $Expected) -eq $Actual)
{
$Message = Get-AssertionMessage -Expected $Expected -Actual $Actual -CustomMessage $CustomMessage -DefaultMessage "Expected <expectedType> '<expected>', to be different than the actual value, but they were the same."
Expand Down
3 changes: 2 additions & 1 deletion src/functions/assert/General/Assert-NotNull.ps1
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
function Assert-NotNull {
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseProcessBlockForPipelineCommand', '')]
param (
[Parameter(Position=1, ValueFromPipeline=$true)]
$Actual,
[String]$CustomMessage
)

$Actual = Collect-Input -ParameterInput $Actual -PipelineInput $local:Input
$Actual = Collect-Input -ParameterInput $Actual -PipelineInput $local:Input -IsInPipeline $MyInvocation.ExpectingInput
if ($null -eq $Actual)
{
$Message = Get-AssertionMessage -Expected $null -Actual $Actual -CustomMessage $CustomMessage -DefaultMessage "Expected not `$null, but got `$null."
Expand Down
10 changes: 5 additions & 5 deletions src/functions/assert/General/Assert-NotSame.ps1
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
function Assert-NotSame {
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseProcessBlockForPipelineCommand', '')]
param (
[Parameter(Position=1, ValueFromPipeline=$true)]
[Parameter(Position = 1, ValueFromPipeline = $true)]
$Actual,
[Parameter(Position=0)]
[Parameter(Position = 0)]
$Expected,
[String]$CustomMessage
)

$Actual = Collect-Input -ParameterInput $Actual -PipelineInput $local:Input
if ([object]::ReferenceEquals($Expected, $Actual))
{
$Actual = Collect-Input -ParameterInput $Actual -PipelineInput $local:Input -IsInPipeline $MyInvocation.ExpectingInput
if ([object]::ReferenceEquals($Expected, $Actual)) {
$Message = Get-AssertionMessage -Expected $Expected -Actual $Actual -CustomMessage $CustomMessage -DefaultMessage "Expected <expectedType> '<expected>', to not be the same instance."
throw [Pester.Factory]::CreateShouldErrorRecord($Message, $MyInvocation.ScriptName, $MyInvocation.ScriptLineNumber, $MyInvocation.Line.TrimEnd([System.Environment]::NewLine), $true)
}
Expand Down
3 changes: 2 additions & 1 deletion src/functions/assert/General/Assert-NotType.ps1
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
function Assert-NotType {
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseProcessBlockForPipelineCommand', '')]
param (
[Parameter(Position = 1, ValueFromPipeline = $true)]
$Actual,
Expand All @@ -7,7 +8,7 @@
[String]$CustomMessage
)

$Actual = Collect-Input -ParameterInput $Actual -PipelineInput $local:Input
$Actual = Collect-Input -ParameterInput $Actual -PipelineInput $local:Input -IsInPipeline $MyInvocation.ExpectingInput
if ($Actual -is $Expected) {
$type = [string]$Expected
$Message = Get-AssertionMessage -Expected $Expected -Actual $Actual -CustomMessage $CustomMessage -DefaultMessage "Expected value to be of different type than '$type', but got '<actual>' of type '<actualType>'."
Expand Down
8 changes: 4 additions & 4 deletions src/functions/assert/General/Assert-Null.ps1
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
function Assert-Null {
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseProcessBlockForPipelineCommand', '')]
param (
[Parameter(Position=1, ValueFromPipeline=$true)]
[Parameter(Position = 1, ValueFromPipeline = $true)]
$Actual,
[String]$CustomMessage
)

$Actual = Collect-Input -ParameterInput $Actual -PipelineInput $local:Input
if ($null -ne $Actual)
{
$Actual = Collect-Input -ParameterInput $Actual -PipelineInput $local:Input -IsInPipeline $MyInvocation.ExpectingInput
if ($null -ne $Actual) {
$Message = Get-AssertionMessage -Expected $null -Actual $Actual -CustomMessage $CustomMessage -DefaultMessage "Expected `$null, but got <actualType> '<actual>'."
throw [Pester.Factory]::CreateShouldErrorRecord($Message, $MyInvocation.ScriptName, $MyInvocation.ScriptLineNumber, $MyInvocation.Line.TrimEnd([System.Environment]::NewLine), $true)
}
Expand Down
13 changes: 6 additions & 7 deletions src/functions/assert/General/Assert-Same.ps1
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
function Assert-Same {
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseProcessBlockForPipelineCommand', '')]
param (
[Parameter(Position=1, ValueFromPipeline=$true)]
[Parameter(Position = 1, ValueFromPipeline = $true)]
$Actual,
[Parameter(Position=0)]
[Parameter(Position = 0)]
$Expected,
[String]$CustomMessage
)

if ($Expected -is [ValueType] -or $Expected -is [string])
{
if ($Expected -is [ValueType] -or $Expected -is [string]) {
throw [ArgumentException]"Assert-Same 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 Assert-Equal instead."
}

$Actual = Collect-Input -ParameterInput $Actual -PipelineInput $local:Input
if (-not ([object]::ReferenceEquals($Expected, $Actual)))
{
$Actual = Collect-Input -ParameterInput $Actual -PipelineInput $local:Input -IsInPipeline $MyInvocation.ExpectingInput
if (-not ([object]::ReferenceEquals($Expected, $Actual))) {
$Message = Get-AssertionMessage -Expected $Expected -Actual $Actual -CustomMessage $CustomMessage -DefaultMessage "Expected <expectedType> '<expected>', to be the same instance but it was not."
throw [Pester.Factory]::CreateShouldErrorRecord($Message, $MyInvocation.ScriptName, $MyInvocation.ScriptLineNumber, $MyInvocation.Line.TrimEnd([System.Environment]::NewLine), $true)
}
Expand Down
3 changes: 2 additions & 1 deletion src/functions/assert/General/Assert-Type.ps1
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
function Assert-Type {
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseProcessBlockForPipelineCommand', '')]
param (
[Parameter(Position = 1, ValueFromPipeline = $true)]
$Actual,
Expand All @@ -7,7 +8,7 @@
[String]$CustomMessage
)

$Actual = Collect-Input -ParameterInput $Actual -PipelineInput $local:Input
$Actual = Collect-Input -ParameterInput $Actual -PipelineInput $local:Input -IsInPipeline $MyInvocation.ExpectingInput
if ($Actual -isnot $Expected) {
$type = [string]$Expected
$Message = Get-AssertionMessage -Expected $Expected -Actual $Actual -CustomMessage $CustomMessage -DefaultMessage "Expected value to be of type '$type', but got '<actual>' of type '<actualType>'."
Expand Down
Loading

0 comments on commit b54b003

Please sign in to comment.