From 344a20cc63bf689319451decc1b0e60c68f1ea56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Jare=C5=A1?= Date: Sat, 18 Jul 2026 12:08:45 +0200 Subject: [PATCH 1/4] Collect code coverage from Invoke-InNewProcess child processes test.ps1 -CC traces the parent process, but the Output and InNewProcess tests run Pester in a child process through Invoke-InNewProcess and assert on its output. So the failure rendering, CI format output and discovery messages are covered by tests, the tracer just never sees them and reports them as missed, which makes the coverage number lie about what is actually tested. When -CC is on the parent now points the children at a drop folder and the same coverage target via PESTER_CC_CHILD_* env vars, which the child process inherits. Each child traces itself the same way the parent does, dumps the path + line:column it hit, and the parent merges those into the measure before the report. Parent and child trace the same files, so a child hit maps onto the same not yet hit point and we just flip it to Hit (the point is a struct, so copy, set, write back, same as the tracer does on a live hit). When -CC is off nothing changes, the child just runs . $ScriptBlock as before. Output.ps1 goes from 74% to 80%, overall from 85.7% to 86.4%. Co-Authored-By: Claude Opus 4.8 --- test.ps1 | 44 ++++++++++++++++++++++++++++++++++++ tst/PTestHelpers.psm1 | 52 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 95 insertions(+), 1 deletion(-) diff --git a/test.ps1 b/test.ps1 index 8939f2e3e..b047bdce7 100644 --- a/test.ps1 +++ b/test.ps1 @@ -64,6 +64,15 @@ if ($CC) { Write-Host "Running Code Coverage" $env:PESTER_CC_DEBUG = 0 $env:PESTER_CC_IN_CC = 1 + # Tests that spawn a child process via Invoke-InNewProcess (e.g. the Output and InNewProcess + # tests) execute Pester code the parent tracer cannot see. Point those children at a shared + # drop folder and the same coverage target; each child traces itself and writes the coordinates + # it hit there, and we merge them into $measure below before the report is generated. + $ccChildDir = Join-Path ([System.IO.Path]::GetTempPath()) "pester-cc-child-$PID" + if (Test-Path $ccChildDir) { Remove-Item $ccChildDir -Recurse -Force } + $null = New-Item -ItemType Directory -Path $ccChildDir -Force + $env:PESTER_CC_CHILD_OUTPUT = $ccChildDir + $env:PESTER_CC_CHILD_TARGET = if ($Inline) { "$PSScriptRoot/bin/Pester*" } else { "$PSScriptRoot/src/*" } $sw = [System.Diagnostics.Stopwatch]::StartNew() $here = {} $bp = Set-PSBreakpoint -Script $PSCommandPath -Line $here.StartPosition.StartLine -Action {} @@ -198,12 +207,47 @@ if ($CC) { & $Stop_TraceScript -Patched $patched $measure = $tracer.Hits + + # Merge the hits collected in child processes (Invoke-InNewProcess) into the in-process + # measure. Parent and child trace the same target, so a child hit at path + "line:column" + # maps onto the same not-yet-hit point here; flip it to Hit (the point is a struct, so we + # copy-modify-write back, exactly like the tracer does on a live hit). + $childFiles = @(Get-ChildItem -Path $ccChildDir -Filter '*.tsv' -File -ErrorAction SilentlyContinue) + $mergedPoints = 0 + foreach ($cf in $childFiles) { + foreach ($rawLine in [System.IO.File]::ReadAllLines($cf.FullName)) { + if ([string]::IsNullOrWhiteSpace($rawLine)) { continue } + $tab = $rawLine.IndexOf("`t") + if ($tab -lt 0) { continue } + $path = $rawLine.Substring(0, $tab) + $key = $rawLine.Substring($tab + 1) + if (-not $measure.ContainsKey($path)) { continue } + $byKey = $measure[$path] + if (-not $byKey.ContainsKey($key)) { continue } + $list = $byKey[$key] + for ($i = 0; $i -lt $list.Count; $i++) { + if (-not $list[$i].Hit) { + $point = $list[$i] + $point.Hit = $true + $list[$i] = $point + $mergedPoints++ + } + } + } + } + Write-Host "Merged code coverage from $($childFiles.Count) child process run(s), marking $mergedPoints additional point(s) as hit." + $coverageReport = & $Get_CoverageReport -CommandCoverage $breakpoints -Measure $measure } finally { if ($null -ne $bp) { $bp | Remove-PSBreakpoint } + if ($ccChildDir -and (Test-Path $ccChildDir)) { + Remove-Item $ccChildDir -Recurse -Force -ErrorAction SilentlyContinue + } + $env:PESTER_CC_CHILD_OUTPUT = $null + $env:PESTER_CC_CHILD_TARGET = $null } [xml] $jaCoCoReport = [xml] (& $Get_JaCoCoReportXml -CommandCoverage $breakpoints -TotalMilliseconds $sw.ElapsedMilliseconds -CoverageReport $coverageReport -ReportRoot $PSScriptRoot) diff --git a/tst/PTestHelpers.psm1 b/tst/PTestHelpers.psm1 index 108ac691d..a77e6bfe2 100644 --- a/tst/PTestHelpers.psm1 +++ b/tst/PTestHelpers.psm1 @@ -8,7 +8,57 @@ param ($PesterPath, [ScriptBlock] $ScriptBlock) Import-Module $PesterPath - . $ScriptBlock + # During a code coverage run (test.ps1 -CC) the parent process traces itself, but the code + # that executes here in the child process is invisible to it. When the parent asks for it + # (via PESTER_CC_CHILD_* env vars, which we inherit) we trace this child the same way and + # dump the coordinates we hit, so the parent can merge them into the single coverage report. + # Note: this scriptblock is stringified and passed to the child as -Command, and on Windows + # PowerShell (legacy native argument passing) only the user ScriptBlock is quote-escaped + # below, so keep this block free of double quotes to avoid mangling the child command line. + # Coverage collection is best-effort: any failure here must fall back to a plain run so the + # test behaves exactly as without coverage. + $ccDir = $env:PESTER_CC_CHILD_OUTPUT + $ccTarget = $env:PESTER_CC_CHILD_TARGET + $ccTracer = $null + $ccPatched = $false + if ($ccDir -and $ccTarget) { + try { + $pesterModule = Get-Module Pester + $enter = & $pesterModule { Get-Command Enter-CoverageAnalysis } + $start = & $pesterModule { Get-Command Start-TraceScript } + $bps = & $enter -CodeCoverage $ccTarget -UseBreakpoints $false + $ccPatched, $ccTracer = & $start $bps + } + catch { + $ccTracer = $null + } + } + try { + . $ScriptBlock + } + finally { + if ($null -ne $ccTracer) { + try { + $stop = & (Get-Module Pester) { Get-Command Stop-TraceScript } + & $stop -Patched $ccPatched + $hitLines = [System.Collections.Generic.List[string]]::new() + $tab = [char]9 + foreach ($path in $ccTracer.Hits.Keys) { + $byKey = $ccTracer.Hits[$path] + foreach ($key in $byKey.Keys) { + foreach ($point in $byKey[$key]) { + if ($point.Hit) { $hitLines.Add($path + $tab + $key); break } + } + } + } + $outFile = Join-Path $ccDir ('child-' + [System.Guid]::NewGuid().ToString('n') + '.tsv') + [System.IO.File]::WriteAllLines($outFile, $hitLines) + } + catch { + # ignore, coverage from this child is simply skipped + } + } + } }.ToString() if ($PSVersionTable.PSVersion -ge '7.3' -and $PSNativeCommandArgumentPassing -ne 'Legacy') { From a5680b7c53cc7340828d8596f324f087d9071eee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Jare=C5=A1?= Date: Sat, 18 Jul 2026 12:44:21 +0200 Subject: [PATCH 2/4] Remove unused internal functions These internal functions have no callers left in src or tst (checked case insensitively, ignoring comments and their own definition), and none are exported. Grouped: - Old v4 assertion messages: the orphaned ShouldFailureMessage and NotShouldFailureMessage pairs for BeGreaterThan, BeIn, BeLessThan, BeLike, BeLikeExactly, BeOfType, BeTrueOrFalse, Contain and HaveCount, plus Get-FailureMessage. The operators build the message inline now. Be, Match and FileContentMatch still call theirs so they stay, and Exist and Throw stay because Should.Tests.ps1 asserts their message functions exist. - Unfinished pretty printer in Format.ps1: Format-Object, Format-Hashtable, Format-Dictionary, Get-DisplayProperty. Format-Nicely returns the value as a string and the advanced path is commented out. - Orphaned helpers across Mock, RSpec, Runtime, Coverage, Debugging and Utility (Run-Test, Merge-CommandCoverage, Show-ParentList, Add-MockBehavior, FindMock, LastThat, Test-IsClosure, Reset-ConflictingParameters, New-BlockWithoutParameterAliases, New-OneTimeBlockSetup, Set-CurrentBlock, Reset-TestSuiteTimer, New-DiscoveredBlockContainerObject, Get-SessionStateHint, Assert-RunInProgress, and the Pester.Utility dictionary helpers). Full test.ps1 run passes. Co-Authored-By: Claude Opus 4.8 --- src/Format.ps1 | 47 +----- src/Pester.Runtime.ps1 | 101 +----------- src/Pester.Utility.ps1 | 110 +------------ src/functions/Coverage.ps1 | 58 +------ src/functions/Mock.ps1 | 175 --------------------- src/functions/Pester.Debugging.ps1 | 24 +-- src/functions/Pester.SessionState.Mock.ps1 | 20 --- src/functions/assertions/BeGreaterThan.ps1 | 12 +- src/functions/assertions/BeIn.ps1 | 6 +- src/functions/assertions/BeLessThan.ps1 | 12 +- src/functions/assertions/BeLike.ps1 | 6 +- src/functions/assertions/BeLikeExactly.ps1 | 6 +- src/functions/assertions/BeOfType.ps1 | 8 +- src/functions/assertions/BeTrueOrFalse.ps1 | 11 +- src/functions/assertions/Contain.ps1 | 6 +- src/functions/assertions/HaveCount.ps1 | 7 +- src/functions/assertions/Should.ps1 | 11 -- 17 files changed, 14 insertions(+), 606 deletions(-) diff --git a/src/Format.ps1 b/src/Format.ps1 index 3d441cd8f..eaba82105 100644 --- a/src/Format.ps1 +++ b/src/Format.ps1 @@ -1,4 +1,4 @@ -# PESTER_BUILD +# PESTER_BUILD if (-not (Get-Variable -Name "PESTER_BUILD" -ValueOnly -ErrorAction Ignore)) { . "$PSScriptRoot/functions/Pester.SafeCommands.ps1" . "$PSScriptRoot/TypeClass.ps1" @@ -27,25 +27,6 @@ function Format-Collection ($Value, [switch]$Pretty) { '@(' + ($formattedCollection -join $separator) + $(if ($trimmed) { ", ...$($count - $limit) more" }) + ')' } -function Format-Object ($Value, $Property, [switch]$Pretty) { - if ($null -eq $Property) { - $Property = $Value.PSObject.Properties | & $SafeCommands['Select-Object'] -ExpandProperty Name - } - $valueType = Get-ShortType $Value - $valueFormatted = ([string]([PSObject]$Value | & $SafeCommands['Select-Object'] -Property $Property)) - - if ($Pretty) { - $margin = " " - $valueFormatted = $valueFormatted ` - -replace '^@{', "@{`n$margin" ` - -replace '; ', ";`n$margin" ` - -replace '}$', "`n}" ` - - } - - $valueFormatted -replace "^@", $valueType -} - function Format-Null { '$null' } @@ -74,28 +55,6 @@ function Format-Number ($Value) { [string]$Value } -function Format-Hashtable ($Value) { - $head = '@{' - $tail = '}' - - $entries = $Value.Keys | & $SafeCommands['Sort-Object'] | & $SafeCommands['ForEach-Object'] { - $formattedValue = Format-Nicely $Value.$_ - "$_=$formattedValue" } - - $head + ( $entries -join '; ') + $tail -} - -function Format-Dictionary ($Value) { - $head = 'Dictionary{' - $tail = '}' - - $entries = $Value.Keys | & $SafeCommands['Sort-Object'] | & $SafeCommands['ForEach-Object'] { - $formattedValue = Format-Nicely $Value.$_ - "$_=$formattedValue" } - - $head + ( $entries -join '; ') + $tail -} - function Format-Nicely ($Value, [switch]$Pretty) { if ($null -eq $Value) { return Format-Null -Value $Value @@ -172,10 +131,6 @@ function Sort-Property ($InputObject, [string[]]$SignificantProperties, $Limit = } -function Get-DisplayProperty ($Value) { - Sort-Property -InputObject $Value -SignificantProperties 'id', 'name' -} - function Get-ShortType ($Value) { if ($null -ne $value) { $type = Format-Type $Value.GetType() diff --git a/src/Pester.Runtime.ps1 b/src/Pester.Runtime.ps1 index 7a3585d74..3d978d4a9 100644 --- a/src/Pester.Runtime.ps1 +++ b/src/Pester.Runtime.ps1 @@ -1,4 +1,4 @@ -# PESTER_BUILD +# PESTER_BUILD if (-not (Get-Variable -Name "PESTER_BUILD" -ValueOnly -ErrorAction Ignore)) { . "$PSScriptRoot/Pester.Utility.ps1" . "$PSScriptRoot/functions/Pester.SafeCommands.ps1" @@ -45,7 +45,6 @@ else { # 'New-PluginObject' # 'New-BlockContainerObject' - # instances $flags = [System.Reflection.BindingFlags]'Instance,NonPublic' $script:SessionStateInternalProperty = [System.Management.Automation.SessionState].GetProperty('Internal', $flags) @@ -449,7 +448,6 @@ function Invoke-Block ($previousBlock) { [Array]::Reverse($frameworkEachBlockTeardowns) [Array]::Reverse($frameworkOneTimeBlockTeardowns) - # setting those values here so they are available for the teardown # BUT they are then set again at the end of the block to make them accurate # so the value on the screen vs the value in the object is slightly different @@ -735,7 +733,6 @@ function Invoke-TestItem { } } - # setting those values here so they are available for the teardown # BUT they are then set again at the end of the block to make them accurate # so the value on the screen vs the value in the object is slightly different @@ -868,17 +865,6 @@ function New-EachBlockTeardown { } # endpoint for adding a setup for all blocks in the current block -function New-OneTimeBlockSetup { - [CmdletBinding()] - param ( - [Parameter(Mandatory = $true)] - [ScriptBlock] $ScriptBlock - ) - if (Is-Discovery) { - $state.CurrentBlock.OneTimeBlockSetup = $ScriptBlock - } -} - # endpoint for adding a teardown for all clocks in the current block function New-OneTimeBlockTeardown { [CmdletBinding()] @@ -905,17 +891,6 @@ function Get-CurrentTest { $state.CurrentTest } -function Set-CurrentBlock { - [CmdletBinding()] - param ( - [Parameter(Mandatory = $true)] - $Block - ) - - $state.CurrentBlock = $Block -} - - function Set-CurrentTest { [CmdletBinding()] param ( @@ -926,7 +901,6 @@ function Set-CurrentTest { $state.CurrentTest = $Test } - function Is-Discovery { $state.Discovery } @@ -1170,7 +1144,6 @@ function Invoke-ContainerRun { $result } - function Discover-Test { [CmdletBinding()] param ( @@ -1216,41 +1189,6 @@ function Discover-Test { $found } -function Run-Test { - param ( - [Parameter(Mandatory = $true)] - [PSObject[]] $Block, - [Parameter(Mandatory = $true)] - [Management.Automation.SessionState] $SessionState - ) - - $state.Discovery = $false - $steps = $state.Plugin.RunStart - if ($null -ne $steps -and 0 -lt @($steps).Count) { - Invoke-PluginStep -Plugins $state.Plugin -Step RunStart -Context @{ - Blocks = $Block - Configuration = $state.PluginConfiguration - Data = $state.PluginData - WriteDebugMessages = $PesterPreference.Debug.WriteDebugMessages.Value - Write_PesterDebugMessage = if ($PesterPreference.Debug.WriteDebugMessages.Value) { $script:SafeCommands['Write-PesterDebugMessage'] } - } -ThrowOnFailure - } - foreach ($rootBlock in $Block) { - Invoke-ContainerRun -RootBlock $rootBlock -SessionState $SessionState - } - - $steps = $state.Plugin.RunEnd - if ($null -ne $steps -and 0 -lt @($steps).Count) { - Invoke-PluginStep -Plugins $state.Plugin -Step RunEnd -Context @{ - Blocks = $Block - Configuration = $state.PluginConfiguration - Data = $state.PluginData - WriteDebugMessages = $PesterPreference.Debug.WriteDebugMessages.Value - Write_PesterDebugMessage = if ($PesterPreference.Debug.WriteDebugMessages.Value) { $script:SafeCommands['Write-PesterDebugMessage'] } - } -ThrowOnFailure - } -} - function Invoke-PluginStep { # [CmdletBinding()] param ( @@ -1450,10 +1388,6 @@ function Invoke-ScriptBlock { } } - - - - # this is what the code below does # . $OuterSetup # & { @@ -1468,7 +1402,6 @@ function Invoke-ScriptBlock { # } # . $OuterTeardown - $wrapperScriptBlock = { # THIS RUNS (MOST OF THE TIME) IN USER SCOPE, BE CAREFUL WHAT YOU PUBLISH AND CONSUME! param($______parameters) @@ -1480,8 +1413,6 @@ function Invoke-ScriptBlock { $______parametersForward = $______parameters } - - try { if ($______parameters.ContextInOuterScope) { $______outerSplat = $______parameters.Context @@ -1744,10 +1675,6 @@ function Invoke-ScriptBlock { return $r } -function Reset-TestSuiteTimer ($o) { - -} - function Switch-Timer { param ( [Parameter(Mandatory)] @@ -2347,7 +2274,6 @@ function PostProcess-DiscoveredBlock { } } - # if we determined that the block should run we can still make it not run if # none of it's children will run if ($b.ShouldRun) { @@ -2433,7 +2359,6 @@ function PostProcess-ExecutedBlock { $Block ) - # traverses the block structure after a block was executed and # and sets the failures correctly so the aggreagatted failures # propagate towards the root so if a child test fails it's block @@ -2488,11 +2413,8 @@ function PostProcess-ExecutedBlock { # setup it is easy all the tests in the block are considered failed, with teardown # not so much, when all tests pass and the teardown itself fails what should be the result? - - # todo: there are two concepts mixed with the "own", because the duration and the test counts act differently. With the counting we are using own as "the count of the tests in this block", but with duration the "own" means "self", that is how long this block itself has run, without the tests. This information might not be important but this should be cleared up before shipping. Same goes with the relation to failure, ownPassed means that the block itself passed (that is no setup or teardown failed in it), even though the underlying tests might fail. - $b.OwnDuration = $b.Duration - $testDuration $b.Passed = -not ($thisBlockFailed -or $anyTestFailed) @@ -2708,27 +2630,6 @@ function New-BlockContainerObject { $c } -function New-DiscoveredBlockContainerObject { - [CmdletBinding()] - param ( - [Parameter(Mandatory)] - $BlockContainer, - [Parameter(Mandatory)] - $Block - ) - - [PSCustomObject] @{ - Type = $BlockContainer.Type - Item = $BlockContainer.Item - # I create a Root block to keep the discovery unaware of containers, - # but I don't want to publish that root block because it contains properties - # that do not make sense on container level like Name and Parent, - # so here we don't want to take the root block but the blocks inside of it - # and copy the rest of the meaningful properties - Blocks = $Block.Blocks - } -} - function Invoke-File { [CmdletBinding()] param( diff --git a/src/Pester.Utility.ps1 b/src/Pester.Utility.ps1 index ed564a8bf..f56171bb1 100644 --- a/src/Pester.Utility.ps1 +++ b/src/Pester.Utility.ps1 @@ -1,4 +1,4 @@ -function or_ { +function or_ { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 0)] @@ -39,25 +39,6 @@ function tryGetProperty_ { # } } -function trySetProperty_ { - [CmdletBinding()] - param ( - [Parameter(Position = 0)] - $InputObject, - [Parameter(Mandatory = $true, Position = 1)] - $PropertyName, - [Parameter(Mandatory = $true, Position = 2)] - $Value - ) - - if ($null -eq $InputObject) { - return - } - - $InputObject.$PropertyName = $Value -} - - # combines collections that are not null or empty, but does not remove null values # from collections so e.g. combineNonNull @(@(1,$null), @(1,2,3), $null, $null, 10) # returns 1, $null, 1, 2, 3, 10 @@ -73,7 +54,6 @@ function combineNonNull_ ($Array) { } } - filter selectNonNull_ { param($Collection) @(foreach ($i in $Collection) { @@ -121,7 +101,6 @@ function notDefined_ { $null -eq ($ExecutionContext.SessionState.PSVariable.GetValue($Name)) } - function Get-CIDebugFlag { # Returns $true when a known CI system has its debug/verbose logging switch enabled. # Mirrors the CI detection used for Output.CIFormat so more CI systems can be added here later. @@ -140,74 +119,6 @@ function Test-CIDebugOutputEnabled ([PesterConfiguration]$PesterPreference) { ('None' -ne $PesterPreference.Output.CIDebugOutput.Value) -and (Get-CIDebugFlag) } - -function sum_ ($InputObject, $PropertyName, $Zero) { - if (none_ $InputObject.Length) { - return $Zero - } - - $acc = $Zero - foreach ($i in $InputObject) { - $acc += $i.$PropertyName - } - - $acc -} - -function tryGetValue_ { - [CmdletBinding()] - param( - $Hashtable, - $Key - ) - - if ($Hashtable.ContainsKey($Key)) { - # do not enumerate so we get the same thing back - # even if it is a collection - $PSCmdlet.WriteObject($Hashtable.$Key, $false) - } -} - -function tryAddValue_ { - [CmdletBinding()] - param( - $Hashtable, - $Key, - $Value - ) - - if (-not $Hashtable.ContainsKey($Key)) { - $null = $Hashtable.Add($Key, $Value) - } -} - -function getOrUpdateValue_ { - [CmdletBinding()] - param( - $Hashtable, - $Key, - $DefaultValue - ) - - if ($Hashtable.ContainsKey($Key)) { - # do not enumerate so we get the same thing back - # even if it is a collection - $PSCmdlet.WriteObject($Hashtable.$Key, $false) - } - else { - $Hashtable.Add($Key, $DefaultValue) - # do not enumerate so we get the same thing back - # even if it is a collection - $PSCmdlet.WriteObject($DefaultValue, $false) - } -} - -function tryRemoveKey_ ($Hashtable, $Key) { - if ($Hashtable.ContainsKey($Key)) { - $Hashtable.Remove($Key) - } -} - function Add-DataToContext ($Destination, $Data) { # works as Merge-Hashtable, but additionally adds _ # which will become $_, and checks if the Data is @@ -233,7 +144,6 @@ function Merge-Hashtable ($Source, $Destination) { } } - function Merge-HashtableOrObject ($Source, $Destination) { if ($Source -isnot [Collections.IDictionary] -and $Source -isnot [PSObject]) { throw "Source must be a Hashtable, IDictionary or a PSObject." @@ -243,7 +153,6 @@ function Merge-HashtableOrObject ($Source, $Destination) { throw "Destination must be a PSObject." } - $sourceIsPSObject = $Source -is [PSObject] $sourceIsDictionary = $Source -is [Collections.IDictionary] $destinationIsPSObject = $Destination -is [PSObject] @@ -437,23 +346,6 @@ function Contain-AnyStringLike ($Filter, $Collection) { } # TODO: Remove? -function Recurse-Up { - param( - [Parameter(Mandatory)] - $InputObject, - [ScriptBlock] $Action - ) - - $i = $InputObject - $level = 0 - while ($null -ne $i) { - &$Action $i - - $level-- - $i = $i.Parent - } -} - function View-Flat { [CmdletBinding()] param ( diff --git a/src/functions/Coverage.ps1 b/src/functions/Coverage.ps1 index 1d7f3dc76..a65784ee3 100644 --- a/src/functions/Coverage.ps1 +++ b/src/functions/Coverage.ps1 @@ -1,4 +1,4 @@ -function Enter-CoverageAnalysis { +function Enter-CoverageAnalysis { [CmdletBinding()] param ( [object[]] $CodeCoverage, @@ -582,53 +582,6 @@ function Get-CoverageHitCommands { $CommandCoverage | & $SafeCommands['Where-Object'] { $_.Breakpoint.HitCount -gt 0 } } -function Merge-CommandCoverage { - param ([object[]] $CommandCoverage) - - # todo: this is a quick implementation of merging lists of breakpoints together, this is needed - # because the code coverage is stored per container and so in the end a lot of commands are missed - # in the container while they are hit in other, what we want is to know how many of the commands were - # hit in at least one file. This simple implementation does not add together the number of hits on each breakpoint - # so the HitCommands is not accurate, it only keeps the first breakpoint that points to that command and it's hit count - # this should be improved in the future. - - # todo: move this implementation to the calling function so we don't need to split and merge the collection twice and we - # can also accumulate the hit count across the different breakpoints - - $hitBps = @{} - $hits = [System.Collections.Generic.List[object]]@() - foreach ($bp in $CommandCoverage) { - if (0 -lt $bp.Breakpoint.HitCount) { - $key = "$($bp.File):$($bp.StartLine):$($bp.StartColumn)" - if (-not $hitBps.ContainsKey($key)) { - # adding to a hashtable to make sure we can look up the keys quickly - # and also to an array list to make sure we can later dump them in the correct order - $hitBps.Add($key, $bp) - $null = $hits.Add($bp) - } - } - } - - $missedBps = @{} - $misses = [System.Collections.Generic.List[object]]@() - foreach ($bp in $CommandCoverage) { - if (0 -eq $bp.Breakpoint.HitCount) { - $key = "$($bp.File):$($bp.StartLine):$($bp.StartColumn)" - if (-not $hitBps.ContainsKey($key)) { - if (-not $missedBps.ContainsKey($key)) { - $missedBps.Add($key, $bp) - $null = $misses.Add($bp) - } - } - } - } - - # this is also not very efficient because in the next step we are splitting this collection again - # into hit and missed breakpoints - $c = $hits.GetEnumerator() + $misses.GetEnumerator() - $c -} - function Merge-CoverageFromParallel { <# .SYNOPSIS @@ -761,7 +714,6 @@ function Get-CoverageReport { $hitCommands = @(Get-CoverageHitCommands -CommandCoverage @($CommandCoverage) | & $SafeCommands['Select-Object'] $properties) $analyzedFiles = @(@($CommandCoverage) | & $SafeCommands['Select-Object'] -ExpandProperty File -Unique) - [pscustomobject] @{ NumberOfCommandsAnalyzed = $CommandCoverage.Count NumberOfFilesAnalyzed = $analyzedFiles.Count @@ -1364,14 +1316,6 @@ function Get-TracerHitLocation ($command) { function Write-Host { } } # function Write-Host { } - function Show-ParentList ($command) { - $c = $command - "`n`nCommand: $c" | Write-Host - $(for ($ast = $c; $null -ne $ast; $ast = $ast.Parent) { - $ast | Select-Object @{n = 'type'; e = { $_.GetType().Name } } , @{n = 'extent'; e = { $_.extent } } - } ) | Format-Table type, extent | Out-String | Write-Host - } - if ($env:PESTER_CC_DEBUG -eq 1) { Write-Host "Processing '$command' at $($command.Extent.StartLineNumber):$($command.Extent.StartColumnNumber) which is $($command.GetType().Name)." } diff --git a/src/functions/Mock.ps1 b/src/functions/Mock.ps1 index 359940e7a..e15321b1b 100644 --- a/src/functions/Mock.ps1 +++ b/src/functions/Mock.ps1 @@ -1,21 +1,4 @@ - -function Add-MockBehavior { - [CmdletBinding()] - param( - [Parameter(Mandatory)] - $Behaviors, - [Parameter(Mandatory)] - $Behavior - ) - - if ($Behavior.IsDefault) { - $Behaviors.Default.Add($Behavior) - } - else { - $Behaviors.Parametrized.Add($Behavior) - } -} function New-MockBehavior { [CmdletBinding()] @@ -155,7 +138,6 @@ function Create-MockHook ($contextInfo, $InvokeMockCallback) { } `$MyInvocation.MyCommand.Mock.PSCmdlet = `$MyInvocation.MyCommand.Mock.ExecutionContext.SessionState.PSVariable.GetValue('local:PSCmdlet') - `if (`$null -ne `$MyInvocation.MyCommand.Mock.PSCmdlet) { `$MyInvocation.MyCommand.Mock.SessionState = `$MyInvocation.MyCommand.Mock.PSCmdlet.SessionState @@ -259,7 +241,6 @@ function Create-MockHook ($contextInfo, $InvokeMockCallback) { ## THIS RUNS IN USER SCOPE, BE CAREFUL WHAT YOU PUBLISH AND CONSUME - # it is possible to remove the script: (and -Scope Script) from here and from the alias, which makes the Mock scope just like a function. # but that breaks mocking inside of Pester itself, because the mock is defined in this function and dies with it # this is a cool concept to play with, but scoping mocks more granularly than per It is not something people asked for, and cleaning up @@ -896,7 +877,6 @@ function Resolve-Command { throw ([System.Management.Automation.CommandNotFoundException] "Could not find Command $CommandName") } - if ($Global -and $command.Name -like 'PesterMock_*' -and $command.Mock.Hook.OwnerRunId -ne [Pester.GlobalMockHook]::CurrentRunId) { # The resolved command is a mock bootstrap, but it belongs to a different (outer) Pester run whose # script-scope alias leaked into this run. Do not reuse it, unwrap to the original command so this @@ -1077,52 +1057,6 @@ function Invoke-MockInternal { } } -function FindMock { - param ( - [Parameter(Mandatory)] - [String] $CommandName, - $ModuleName, - [Parameter(Mandatory)] - [HashTable] $MockTable - ) - - $result = @{ - Mock = $null - MockFound = $false - CommandName = $CommandName - ModuleName = $ModuleName - } - if ($PesterPreference.Debug.WriteDebugMessages.Value) { - Write-PesterDebugMessage -Scope Mock "Looking for mock $($ModuleName)||$CommandName." - } - $MockTable["$($ModuleName)||$CommandName"] - - if ($null -ne $mock) { - if ($PesterPreference.Debug.WriteDebugMessages.Value) { - Write-PesterDebugMessage -Scope Mock "Found mock $(if (-not [string]::IsNullOrEmpty($ModuleName)) {"with module name $($ModuleName)"})||$CommandName." - } - $result.MockFound = $true - } - else { - if ($PesterPreference.Debug.WriteDebugMessages.Value) { - Write-PesterDebugMessage -Scope Mock "No mock found, re-trying without module name ||$CommandName." - } - $mock = $MockTable["||$CommandName"] - $result.ModuleName = $null - if ($null -ne $mock) { - if ($PesterPreference.Debug.WriteDebugMessages.Value) { - Write-PesterDebugMessage -Scope Mock "Found mock without module name, setting the target module to empty." - } - $result.MockFound = $true - } - else { - $result.MockFound = $false - } - } - - return $result -} - function FindMatchingBehavior { param ( [Parameter(Mandatory)] @@ -1188,22 +1122,6 @@ function FindMatchingBehavior { return $null, $failedFilterInvocations } -function LastThat { - param ( - $Collection, - $Predicate - ) - - $count = $Collection.Count - for ($i = $count; $i -gt 0; $i--) { - $item = $Collection[$i] - if (&$Predicate $Item) { - return $Item - } - } -} - - function ExecuteBehavior { param ( $Behavior, @@ -1895,29 +1813,6 @@ function Get-DynamicParametersForMockedFunction { } } -function Test-IsClosure { - [CmdletBinding()] - param ( - [Parameter(Mandatory = $true)] - [scriptblock] - $ScriptBlock - ) - - $sessionStateInternal = $script:ScriptBlockSessionStateInternalProperty.GetValue($ScriptBlock) - if ($null -eq $sessionStateInternal) { - return $false - } - - $flags = [System.Reflection.BindingFlags]'Instance,NonPublic' - $module = $sessionStateInternal.GetType().GetProperty('Module', $flags).GetValue($sessionStateInternal, $null) - - return ( - $null -ne $module -and - $module.Name -match '^__DynamicModule_([a-f\d-]+)$' -and - $null -ne ($matches[1] -as [guid]) - ) -} - function Remove-MockFunctionsAndAliases ($SessionState) { # when a test is terminated (e.g. by stopping at a breakpoint and then stopping the execution of the script) # the aliases and bootstrap functions for the currently mocked functions will remain in place @@ -2090,33 +1985,6 @@ function Repair-EncodingParameters { $repairedMetadata } -function Reset-ConflictingParameters { - [CmdletBinding()] - [OutputType([hashtable])] - param( - [Parameter(Mandatory = $true)] - [hashtable] - $BoundParameters - ) - - $parameters = $BoundParameters.Clone() - # unnecessary function call that could be replaced by variable access, but is needed for tests - $names = Get-ConflictingParameterNames - - foreach ($param in $names) { - $fixedName = "_$param" - - if (-not $parameters.ContainsKey($fixedName)) { - continue - } - - $parameters[$param] = $parameters[$fixedName] - $null = $parameters.Remove($fixedName) - } - - $parameters -} - $script:ConflictingParameterNames = @( '?' 'ConsoleFileName' @@ -2164,49 +2032,6 @@ function Get-ScriptBlockAST { } # TODO: Remove? -function New-BlockWithoutParameterAliases { - [OutputType([scriptblock])] - param( - [Parameter(Mandatory = $true)] - [ValidateNotNull()] - [System.Management.Automation.CommandMetadata] - $Metadata, - [Parameter(Mandatory = $true)] - [ValidateNotNull()] - [scriptblock] - $Block - ) - try { - $params = $Metadata.Parameters.Values - $ast = Get-ScriptBlockAST $Block - $blockText = $ast.Extent.Text - $variables = [array]($Ast.FindAll( { param($ast) $ast -is [System.Management.Automation.Language.VariableExpressionAst] }, $true)) - [array]::Reverse($variables) - - foreach ($var in $variables) { - $varName = $var.VariablePath.UserPath - $length = $varName.Length - - foreach ($param in $params) { - if ($param.Aliases -contains $varName) { - $startIndex = $var.Extent.StartOffset - $ast.Extent.StartOffset + 1 # move one position after the dollar sign - - $blockText = $blockText.Remove($startIndex, $length).Insert($startIndex, $param.Name) - - break # It is safe to stop checking for further params here, since aliases cannot be shared by parameters - } - } - } - - $Block = [scriptblock]::Create($blockText) - - $Block - } - catch { - $PSCmdlet.ThrowTerminatingError($_) - } -} - function Repair-EnumParameters { param ( [string] diff --git a/src/functions/Pester.Debugging.ps1 b/src/functions/Pester.Debugging.ps1 index 50d89af06..29c10fd85 100644 --- a/src/functions/Pester.Debugging.ps1 +++ b/src/functions/Pester.Debugging.ps1 @@ -1,4 +1,4 @@ -function Count-Scopes { +function Count-Scopes { param( [Parameter(Mandatory = $true)] $ScriptBlock) @@ -52,7 +52,6 @@ function Write-ScriptBlockInvocationHint { return } - if ($PesterPreference.Debug.WriteDebugMessages.Value) { Write-PesterDebugMessage -Scope SessionState -LazyMessage { $scope = Get-ScriptBlockHint $ScriptBlock @@ -145,26 +144,6 @@ function Set-SessionStateHint { } } -function Get-SessionStateHint { - param( - [Parameter(Mandatory = $true)] - [Management.Automation.SessionState] $SessionState - ) - - if ($script:DisableScopeHints) { - return - } - - # the hint is also attached to the session state object, but sessionstate objects are recreated while - # the internal state stays static so to see the hint on object that we receive via $PSCmdlet.SessionState we need - # to look at the InternalSessionState. the internal state should be never null so just looking there is enough - $flags = [System.Reflection.BindingFlags]'Instance,NonPublic' - $internalSessionState = $SessionState.GetType().GetProperty('Internal', $flags).GetValue($SessionState, $null) - if (Test-Hint $internalSessionState) { - $internalSessionState.Hint - } -} - function Set-ScriptBlockHint { param( [Parameter(Mandatory = $true)] @@ -230,7 +209,6 @@ function Get-ScriptBlockHint { $flags = [System.Reflection.BindingFlags]'Instance,NonPublic' $internalSessionState = $ScriptBlock.GetType().GetProperty('SessionStateInternal', $flags).GetValue($ScriptBlock, $null) - if ($null -ne $internalSessionState -and (Test-Hint $internalSessionState)) { return $internalSessionState.Hint } diff --git a/src/functions/Pester.SessionState.Mock.ps1 b/src/functions/Pester.SessionState.Mock.ps1 index 033671025..b3a1c8a24 100644 --- a/src/functions/Pester.SessionState.Mock.ps1 +++ b/src/functions/Pester.SessionState.Mock.ps1 @@ -290,7 +290,6 @@ function Mock { Write-PesterDebugMessage -Scope Mock -Message "Setting up $(if ($ParameterFilter) {"parametrized"} else {"default"}) mock for$(if ($ModuleName) {" $ModuleName -"}) $CommandName." } - if ($PesterPreference.Debug.WriteDebugMessages.Value) { $null = Set-ScriptBlockHint -Hint "Unbound MockWith - Captured in Mock" -ScriptBlock $MockWith $null = if ($ParameterFilter) { Set-ScriptBlockHint -Hint "Unbound ParameterFilter - Captured in Mock" -ScriptBlock $ParameterFilter } @@ -467,7 +466,6 @@ function Get-VerifiableBehaviors { $behaviors } - function Get-AssertMockTable { [CmdletBinding()] param( @@ -496,7 +494,6 @@ function Get-AssertMockTable { # we are in test and we care only about the test scope, # this is easy, we just look for call history of the command - $history = if ($Frame.Frame.PluginData.Mock.CallHistory.ContainsKey($Key)) { # do not enumerate so we get the same thing back # even if it is a collection @@ -545,7 +542,6 @@ function Get-AssertMockTable { } } - # this is harder, we have scope and we are in a block, we need to look # in this block and any child for mock calls @@ -578,7 +574,6 @@ function Get-AssertMockTable { $block = $i } - # we have our block so we need to collect all the history for the given mock $history = [System.Collections.Generic.List[Object]]@() @@ -593,7 +588,6 @@ function Get-AssertMockTable { $callHistory = $mockData.CallHistory - $v = if ($callHistory.ContainsKey($key)) { $callHistory.$key } @@ -612,7 +606,6 @@ function Get-AssertMockTable { } } - return @{ "$key" = [Collections.Generic.List[object]]@($history) } @@ -1287,16 +1280,3 @@ function Invoke-Mock { Invoke-MockInternal @PSBoundParameters -Behaviors $behaviors -CallHistory $callHistory } -function Assert-RunInProgress { - param( - [Parameter(Mandatory)] - [String] $CommandName - ) - - if (Is-Discovery) { - throw "$CommandName can run only during Run, but not during Discovery." - } -} - - - diff --git a/src/functions/assertions/BeGreaterThan.ps1 b/src/functions/assertions/BeGreaterThan.ps1 index c72076e99..655878dfe 100644 --- a/src/functions/assertions/BeGreaterThan.ps1 +++ b/src/functions/assertions/BeGreaterThan.ps1 @@ -1,4 +1,4 @@ -function Should-BeGreaterThanAssertion($ActualValue, $ExpectedValue, [switch] $Negate, [string] $Because) { +function Should-BeGreaterThanAssertion($ActualValue, $ExpectedValue, [switch] $Negate, [string] $Because) { <# .SYNOPSIS Asserts that a number (or other comparable value) is greater than an expected value. @@ -30,7 +30,6 @@ } } - function Should-BeLessOrEqual($ActualValue, $ExpectedValue, [switch] $Negate, [string] $Because) { <# .SYNOPSIS @@ -85,12 +84,3 @@ Set-ShouldOperatorHelpMessage -OperatorName BeLessOrEqual ` -HelpMessage "Asserts that a number (or other comparable value) is lower than, or equal to an expected value. Uses PowerShell's -le operator to compare the two values." #keeping tests happy -function ShouldBeGreaterThanFailureMessage() { -} -function NotShouldBeGreaterThanFailureMessage() { -} - -function ShouldBeLessOrEqualFailureMessage() { -} -function NotShouldBeLessOrEqualFailureMessage() { -} diff --git a/src/functions/assertions/BeIn.ps1 b/src/functions/assertions/BeIn.ps1 index a029613bf..1bc8e13d7 100644 --- a/src/functions/assertions/BeIn.ps1 +++ b/src/functions/assertions/BeIn.ps1 @@ -1,4 +1,4 @@ -function Should-BeInAssertion($ActualValue, $ExpectedValue, [switch] $Negate, [string] $Because) { +function Should-BeInAssertion($ActualValue, $ExpectedValue, [switch] $Negate, [string] $Because) { <# .SYNOPSIS Asserts that a collection of values contain a specific value. @@ -51,7 +51,3 @@ Set-ShouldOperatorHelpMessage -OperatorName BeIn ` -HelpMessage "Asserts that a collection of values contain a specific value. Uses PowerShell's -contains operator to confirm." -function ShouldBeInFailureMessage() { -} -function NotShouldBeInFailureMessage() { -} diff --git a/src/functions/assertions/BeLessThan.ps1 b/src/functions/assertions/BeLessThan.ps1 index 50b3621a8..9412c7cc3 100644 --- a/src/functions/assertions/BeLessThan.ps1 +++ b/src/functions/assertions/BeLessThan.ps1 @@ -1,4 +1,4 @@ -function Should-BeLessThanAssertion($ActualValue, $ExpectedValue, [switch] $Negate, [string] $Because) { +function Should-BeLessThanAssertion($ActualValue, $ExpectedValue, [switch] $Negate, [string] $Because) { <# .SYNOPSIS Asserts that a number (or other comparable value) is lower than an expected value. @@ -30,7 +30,6 @@ } } - function Should-BeGreaterOrEqual($ActualValue, $ExpectedValue, [switch] $Negate, [string] $Because) { <# .SYNOPSIS @@ -85,12 +84,3 @@ Set-ShouldOperatorHelpMessage -OperatorName BeGreaterOrEqual ` -HelpMessage "Asserts that a number (or other comparable value) is greater than or equal to an expected value. Uses PowerShell's -ge operator to compare the two values." #keeping tests happy -function ShouldBeLessThanFailureMessage() { -} -function NotShouldBeLessThanFailureMessage() { -} - -function ShouldBeGreaterOrEqualFailureMessage() { -} -function NotShouldBeGreaterOrEqualFailureMessage() { -} diff --git a/src/functions/assertions/BeLike.ps1 b/src/functions/assertions/BeLike.ps1 index 5502ad56b..32688e541 100644 --- a/src/functions/assertions/BeLike.ps1 +++ b/src/functions/assertions/BeLike.ps1 @@ -1,4 +1,4 @@ -function Should-BeLikeAssertion($ActualValue, $ExpectedValue, [switch] $Negate, [String] $Because) { +function Should-BeLikeAssertion($ActualValue, $ExpectedValue, [switch] $Negate, [String] $Because) { <# .SYNOPSIS Asserts that the actual value matches a wildcard pattern using PowerShell's -like operator. @@ -59,7 +59,3 @@ Set-ShouldOperatorHelpMessage -OperatorName BeLike ` -HelpMessage "Asserts that the actual value matches a wildcard pattern using PowerShell's -like operator. This comparison is not case-sensitive." -function ShouldBeLikeFailureMessage() { -} -function NotShouldBeLikeFailureMessage() { -} diff --git a/src/functions/assertions/BeLikeExactly.ps1 b/src/functions/assertions/BeLikeExactly.ps1 index c0532a34d..4e48c0e00 100644 --- a/src/functions/assertions/BeLikeExactly.ps1 +++ b/src/functions/assertions/BeLikeExactly.ps1 @@ -1,4 +1,4 @@ -function Should-BeLikeExactlyAssertion($ActualValue, $ExpectedValue, [switch] $Negate, [String] $Because) { +function Should-BeLikeExactlyAssertion($ActualValue, $ExpectedValue, [switch] $Negate, [String] $Because) { <# .SYNOPSIS Asserts that the actual value matches a wildcard pattern using PowerShell's -like operator. @@ -58,7 +58,3 @@ Set-ShouldOperatorHelpMessage -OperatorName BeLikeExactly ` -HelpMessage "Asserts that the actual value matches a wildcard pattern using PowerShell's -like operator. This comparison is case-sensitive." -function ShouldBeLikeExactlyFailureMessage() { -} -function NotShouldBeLikeExactlyFailureMessage() { -} diff --git a/src/functions/assertions/BeOfType.ps1 b/src/functions/assertions/BeOfType.ps1 index b2b022a55..36a5599b8 100644 --- a/src/functions/assertions/BeOfType.ps1 +++ b/src/functions/assertions/BeOfType.ps1 @@ -1,4 +1,4 @@ - + function Should-BeOfTypeAssertion($ActualValue, $ExpectedType, [switch] $Negate, [string]$Because) { <# .SYNOPSIS @@ -154,7 +154,6 @@ function Should-BeOfTypeAssertion($ActualValue, $ExpectedType, [switch] $Negate, } } - & $script:SafeCommands['Add-ShouldOperator'] -Name BeOfType ` -InternalName Should-BeOfTypeAssertion ` -Test ${function:Should-BeOfTypeAssertion} ` @@ -163,8 +162,3 @@ function Should-BeOfTypeAssertion($ActualValue, $ExpectedType, [switch] $Negate, Set-ShouldOperatorHelpMessage -OperatorName BeOfType ` -HelpMessage "Asserts that the actual value should be an object of a specified type (or a subclass of the specified type) using PowerShell's -is operator." -function ShouldBeOfTypeFailureMessage() { -} - -function NotShouldBeOfTypeFailureMessage() { -} diff --git a/src/functions/assertions/BeTrueOrFalse.ps1 b/src/functions/assertions/BeTrueOrFalse.ps1 index 3c3c74297..1da9131a4 100644 --- a/src/functions/assertions/BeTrueOrFalse.ps1 +++ b/src/functions/assertions/BeTrueOrFalse.ps1 @@ -1,4 +1,4 @@ -function Should-BeTrueAssertion($ActualValue, [switch] $Negate, [string] $Because) { +function Should-BeTrueAssertion($ActualValue, [switch] $Negate, [string] $Because) { <# .SYNOPSIS Asserts that the value is true, or truthy. @@ -86,7 +86,6 @@ function Should-BeFalseAssertion($ActualValue, [switch] $Negate, $Because) { } } - & $script:SafeCommands['Add-ShouldOperator'] -Name BeTrue ` -InternalName Should-BeTrueAssertion ` -Test ${function:Should-BeTrueAssertion} @@ -102,11 +101,3 @@ Set-ShouldOperatorHelpMessage -OperatorName BeFalse ` -HelpMessage "Asserts that the value is false, or falsy." # to keep tests happy -function ShouldBeTrueFailureMessage($ActualValue) { -} -function NotShouldBeTrueFailureMessage($ActualValue) { -} -function ShouldBeFalseFailureMessage($ActualValue) { -} -function NotShouldBeFalseFailureMessage($ActualValue) { -} diff --git a/src/functions/assertions/Contain.ps1 b/src/functions/assertions/Contain.ps1 index 6ecd43f83..dfddb951a 100644 --- a/src/functions/assertions/Contain.ps1 +++ b/src/functions/assertions/Contain.ps1 @@ -1,4 +1,4 @@ -function Should-ContainAssertion($ActualValue, $ExpectedValue, [switch] $Negate, [string] $Because) { +function Should-ContainAssertion($ActualValue, $ExpectedValue, [switch] $Negate, [string] $Because) { <# .SYNOPSIS Asserts that collection contains a specific value. @@ -52,7 +52,3 @@ Set-ShouldOperatorHelpMessage -OperatorName Contain ` -HelpMessage "Asserts that collection contains a specific value. Uses PowerShell's -contains operator to confirm." -function ShouldContainFailureMessage() { -} -function NotShouldContainFailureMessage() { -} diff --git a/src/functions/assertions/HaveCount.ps1 b/src/functions/assertions/HaveCount.ps1 index b184e182b..c71141351 100644 --- a/src/functions/assertions/HaveCount.ps1 +++ b/src/functions/assertions/HaveCount.ps1 @@ -1,4 +1,4 @@ -function Should-HaveCountAssertion($ActualValue, [int] $ExpectedValue, [switch] $Negate, [string] $Because) { +function Should-HaveCountAssertion($ActualValue, [int] $ExpectedValue, [switch] $Negate, [string] $Because) { <# .SYNOPSIS Asserts that a collection has the expected amount of items. @@ -24,7 +24,6 @@ $succeeded = -not $succeeded } - if (-not $succeeded) { if ($Negate) { @@ -94,7 +93,3 @@ Set-ShouldOperatorHelpMessage -OperatorName HaveCount ` -HelpMessage 'Asserts that a collection has the expected amount of items.' -function ShouldHaveCountFailureMessage() { -} -function NotShouldHaveCountFailureMessage() { -} diff --git a/src/functions/assertions/Should.ps1 b/src/functions/assertions/Should.ps1 index c0b8b1602..a4fd47391 100644 --- a/src/functions/assertions/Should.ps1 +++ b/src/functions/assertions/Should.ps1 @@ -1,14 +1,3 @@ -function Get-FailureMessage($assertionEntry, $negate, $value, $expected) { - if ($negate) { - $failureMessageFunction = $assertionEntry.GetNegativeFailureMessage - } - else { - $failureMessageFunction = $assertionEntry.GetPositiveFailureMessage - } - - return (& $failureMessageFunction $value $expected) -} - function Should { <# .SYNOPSIS From e1a7972b9598454b1c0b6d58bc97fd6fba978a9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Jare=C5=A1?= Date: Sat, 18 Jul 2026 22:10:54 +0200 Subject: [PATCH 3/4] Rename Count-Scopes to Get-ScopeCount Count is not an approved verb and Scopes is plural, PSScriptAnalyzer flags it. Internal debug helper, only caller is Write-ScriptBlockInvocationHint. Co-Authored-By: Claude Opus 4.8 --- src/functions/Pester.Debugging.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/functions/Pester.Debugging.ps1 b/src/functions/Pester.Debugging.ps1 index 29c10fd85..074064ba1 100644 --- a/src/functions/Pester.Debugging.ps1 +++ b/src/functions/Pester.Debugging.ps1 @@ -1,4 +1,4 @@ -function Count-Scopes { +function Get-ScopeCount { param( [Parameter(Mandatory = $true)] $ScriptBlock) @@ -55,7 +55,7 @@ function Write-ScriptBlockInvocationHint { if ($PesterPreference.Debug.WriteDebugMessages.Value) { Write-PesterDebugMessage -Scope SessionState -LazyMessage { $scope = Get-ScriptBlockHint $ScriptBlock - $count = Count-Scopes -ScriptBlock $ScriptBlock + $count = Get-ScopeCount -ScriptBlock $ScriptBlock "Invoking scriptblock from location '$Hint' in state '$scope', $count scopes deep:" "{" $ScriptBlock.ToString().Trim() From 865ad7c56ae303ff8589af750b6d1ec3ade47377 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Jare=C5=A1?= Date: Sat, 18 Jul 2026 22:35:50 +0200 Subject: [PATCH 4/4] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jakub Jareš --- src/Pester.Utility.ps1 | 1 - src/functions/Mock.ps1 | 1 - 2 files changed, 2 deletions(-) diff --git a/src/Pester.Utility.ps1 b/src/Pester.Utility.ps1 index f56171bb1..0417b9626 100644 --- a/src/Pester.Utility.ps1 +++ b/src/Pester.Utility.ps1 @@ -345,7 +345,6 @@ function Contain-AnyStringLike ($Filter, $Collection) { return $false } -# TODO: Remove? function View-Flat { [CmdletBinding()] param ( diff --git a/src/functions/Mock.ps1 b/src/functions/Mock.ps1 index e15321b1b..fba26f261 100644 --- a/src/functions/Mock.ps1 +++ b/src/functions/Mock.ps1 @@ -2031,7 +2031,6 @@ function Get-ScriptBlockAST { return $ast } -# TODO: Remove? function Repair-EnumParameters { param ( [string]