Skip to content

Commit

Permalink
Exclude duplicate files for Run.Path and CodeCoverage.Path (#2535)
Browse files Browse the repository at this point in the history
* Return only unique files in Find-File

* Remove redundant loop in New-PesterContainer

* Refactor Get-CodeCoverageFilePaths and remove duplicates

* Improve perf in New-PesterContainer
  • Loading branch information
fflaten authored Jul 10, 2024
1 parent 7304ff9 commit 99760df
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 46 deletions.
31 changes: 13 additions & 18 deletions src/Pester.RSpec.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@
[string] $Extension
)


$files =
foreach ($p in $Path) {
$files = foreach ($p in $Path) {
if ([String]::IsNullOrWhiteSpace($p)) {
continue
}
Expand Down Expand Up @@ -66,11 +64,13 @@
}
}

Filter-Excluded -Files $files -ExcludePath $ExcludePath | & $SafeCommands['Where-Object'] { $_ }
# Deduplicate files if overlapping -Path values
$uniquePaths = [System.Collections.Generic.HashSet[string]]::new(@($files).Count)
$uniqueFiles = foreach ($f in $files) { if ($uniquePaths.Add($f.FullName)) { $f } }
Filter-Excluded -Files $uniqueFiles -ExcludePath $ExcludePath | & $SafeCommands['Where-Object'] { $_ }
}

function Filter-Excluded ($Files, $ExcludePath) {

if ($null -eq $ExcludePath -or @($ExcludePath).Length -eq 0) {
return @($Files)
}
Expand All @@ -81,12 +81,9 @@ function Filter-Excluded ($Files, $ExcludePath) {
$excluded = $false

foreach ($exclusion in (@($ExcludePath) -replace "/", "\")) {
if ($excluded) {
continue
}

if ($p -like $exclusion) {
$excluded = $true
continue
}
}

Expand Down Expand Up @@ -571,15 +568,13 @@ function New-PesterContainer {
}

if ("Path" -eq $kind) {
# the @() is significant here, it will make it iterate even if there are no data
# which allows files without data to run
foreach ($d in @($dt)) {
foreach ($p in $Path) {
# resolve the path we are given in the same way we would resolve -Path on Invoke-Pester
$files = @(Find-File -Path $p -ExcludePath $PesterPreference.Run.ExcludePath.Value -Extension $PesterPreference.Run.TestExtension.Value)
foreach ($file in $files) {
New-BlockContainerObject -File $file -Data $d
}
# resolve the path we are given in the same way we would resolve -Path on Invoke-Pester
$files = @(Find-File -Path $Path -ExcludePath $PesterPreference.Run.ExcludePath.Value -Extension $PesterPreference.Run.TestExtension.Value)
foreach ($file in $files) {
# the @() is significant here, it will make it iterate even if there are no data
# which allows files without data to run
foreach ($d in @($dt)) {
New-BlockContainerObject -File $file -Data $d
}
}
}
Expand Down
37 changes: 9 additions & 28 deletions src/functions/Coverage.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -211,54 +211,35 @@ function Resolve-CoverageInfo {

$filePaths = Get-CodeCoverageFilePaths -Paths $resolvedPaths -IncludeTests $includeTests -RecursePaths $recursePaths

$params = @{
$commonParams = @{
StartLine = $UnresolvedCoverageInfo.StartLine
EndLine = $UnresolvedCoverageInfo.EndLine
Class = $UnresolvedCoverageInfo.Class
Function = $UnresolvedCoverageInfo.Function
}

foreach ($filePath in $filePaths) {
$params['Path'] = $filePath
New-CoverageInfo @params
New-CoverageInfo @commonParams -Path $filePath
}
}

function Get-CodeCoverageFilePaths {
param (
[object]$Paths,
[string[]]$Paths,
[bool]$IncludeTests,
[bool]$RecursePaths
)

$testsPattern = "*$($PesterPreference.Run.TestExtension.Value)"

$filePaths = foreach ($path in $Paths) {
$item = & $SafeCommands['Get-Item'] -LiteralPath $path
if ($item -is [System.IO.FileInfo] -and ('.ps1', '.psm1') -contains $item.Extension -and ($IncludeTests -or $item.Name -notlike $testsPattern)) {
$item.FullName
}
elseif ($item -is [System.IO.DirectoryInfo]) {
$children = foreach ($i in & $SafeCommands['Get-ChildItem'] -LiteralPath $item) {
# if we recurse paths return both directories and files so they can be resolved in the
# recursive call to Get-CodeCoverageFilePaths, otherwise return just files
if ($RecursePaths) {
$i.PSPath
}
elseif (-not $i.PSIsContainer) {
$i.PSPath
}
}
Get-CodeCoverageFilePaths -Paths $children -IncludeTests $IncludeTests -RecursePaths $RecursePaths
}
elseif (-not $item.PsIsContainer) {
# todo: enable this warning for non wildcarded paths? otherwise it prints a ton of warnings for documentation and so on when using "folder/*" wildcard
# & $SafeCommands['Write-Warning'] "CodeCoverage path '$path' resolved to a non-PowerShell file '$($item.FullName)'; this path will not be part of the coverage report."
[string[]] $filteredFiles = @(foreach ($file in (& $SafeCommands['Get-ChildItem'] -LiteralPath $Paths -File -Recurse:$RecursePaths)) {
if (('.ps1', '.psm1') -contains $file.Extension -and ($IncludeTests -or $file.Name -notlike $testsPattern)) {
$file.FullName
}
}

return $filePaths
})

$uniqueFiles = [System.Collections.Generic.HashSet[string]]::new($filteredFiles)
return $uniqueFiles
}

function Get-CoverageBreakpoints {
Expand Down
5 changes: 5 additions & 0 deletions tst/Pester.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,11 @@ InPesterModuleScope {
($paths -contains (Join-Path $testDrive "SomeOtherFile.Tests.ps1")) | Should -Be $true
}

It 'Deduplicates filepaths when the provided paths overlaps' {
$result = @(Find-File 'TestDrive:\*.ps1','TestDrive:\*.ps1' -Extension '.Tests.ps1')
$result.Count | Should -Be 2
}

# It 'Assigns empty array and hashtable to the Arguments and Parameters properties when none are specified by the caller' {
# $result = @(Find-File 'TestDrive:\SomeFile.ps1' -Extension ".Tests.ps1")

Expand Down

0 comments on commit 99760df

Please sign in to comment.